Webpack 的简单介绍

本文介绍了一些 webpack 的核心概念以及一些概念术语,并对核心配置作了一些简单的用法讲解。建议刚刚接触 Webpack 的朋友能够先了解一下。想了解更多 Webpack 使用以及配置的话能够参考个人下一篇文章: 从零开始搭建一个 Webpack 开发环境配置(附 Demo)css


为何须要使用 webpack

  • 模块化开发的趋势 咱们在开发的过程当中,以前都是使用引入 script 的方式进行各类工具和插件的引入,可是这样会形成很大程度上的全局污染,因此引入了 模块化 的概念,可是不论是 commomJs 仍是 CMD,AMD 的方式,浏览器都没法识别,而使用 webpack 就能够自动的将文件编译成浏览器能够识别的代码node

  • less、sass 以及 ES6 语法的使用 一样的,直接使用 less、sass 和 ES6 语法,直接使用,浏览器甚至 node 环境也没法正常识别,因此这时候 loader 就派上用场了,可使用 less-loader、sass-loader 以及 babel-lodaer 对对应的文件进行转换以后,就能够正常的编译了webpack

  • 监听文件的变化并自动刷新网页,作到实时预览web

  • 提供 HTTP 服务而不是使用本地文件预览npm

  • 对于打包后的文件进行压缩,模块拆分,减少打包后的文件体积数组

  • 等等还有不少别的优点,这里我就不一一列举了浏览器


webpack 安装

  • 全局安装:缓存

    npm install --global webpack
    复制代码
  • 本地安装:sass

    npm install --save-dev webpack
    npm install --save-dev webpack-cli
    复制代码

Webpack 概念

webpack 是一个可高度配置的现代 JavaScript 应用程序模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序须要的每一个模块,而后将全部这些模块打包成一个或多个 bundle。bash

Webpack 核心概念

入口

入口点能够告诉 webpack 从哪里启动以及遵循依赖关系图,以此知道要打包什么东西。你能够考虑将待打包文件的根目录做为你应用程序的入口点。

我的理解:入口就是 webpack 在处理应用程序时,须要知道从哪一个文件开始执行,这个文件就是整个程序的入口文件。

用法:entry: string|Array|Object

基本用法

webpack.config.js

const config = {
  entry: './src/index.js'
};

module.exports = config;
复制代码

数组语法

通常适用于多页面应用,多个入口的场景。

webpack.config.js

const config = {
  entry: ['./src/entry1', './src/entry2']
};

module.exports = config;
复制代码

对象语法

通常适用于分离 应用程序(app) 和 第三方库(vendor) 入口。

webpack.config.js

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

module.exports = config;
复制代码

配置动态入口

假如项目里有多个页面须要为每一个页面的入口配置一个 Entry ,但这些页面的数量可能会不断增加,则这时 Entry 的配置会受到到其余因素的影响致使不能写成静态的值。

webpack.config.js

// 同步函数
entry: () => {
  return {
    a:'./pages/a',
    b:'./pages/b',
  }
};
// 异步函数
entry: () => {
  return new Promise((resolve)=>{
    resolve({
       a:'./pages/a',
       b:'./pages/b',
    });
  });
};
复制代码

输出

上面既然已经有入口文件了,那么 webpack 执行了一系列操做以后,生成的新的打包后的文件应该放到哪儿呢,因此咱们须要指定一下。

在 webpack 中配置 output 属性的最低要求是,将它的值设置为一个对象,包括如下两点:

  • filename 用于输出文件的文件名
  • 目标输出目录 path 的绝对路径

基本用法

webpack.config.js

const path = require('path');

const config = {
    entry: './src/index.js',
    output: {
        // 最基本的两个配置要求
        filename: 'bundle.js',  // 输出文件的文件名
        path: path.resolve(__dirname, 'dist')   // 目标输出目录 path 的绝对路径,这里必须是绝对路径
    }
};

module.exports = config;
复制代码

多个入口起点

若是配置建立了多个单独的 "chunk",则应该使用占位符(参考*内置的占位符变量*)来确保每一个文件具备惟一的名称。

webpack.config.js

const path = require('path');

const config = {
  output: {
    // 最基本的两个配置要求
    filename: '[name]-bundle.js',  // 输出文件的文件名
    path: path.resolve(__dirname, 'dist')   // 目标输出目录 path 的绝对路径
  }
};

module.exports = config;
复制代码

内置的占位符变量

变量名 含义
id Chunk 的惟一标识,从0开始
name Chunk 的名称
hash Chunk 的惟一标识的 Hash 值
chunkhash Chunk 内容的 Hash 值

loader

loader 用于对模块的源代码进行转换。loader 可使你在 importrequire() 或"加载"模块时预处理文件。 loader 能够将文件从不一样的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至容许你直接在 JavaScript 模块中 import CSS文件!

基本使用

例如:加载 css 模块:

  • 安装对应的 loader

    npm install --save-dev style-loader css-loader
    复制代码
  • 而后指示 webpack 对每一个 .css 使用 css-loader 和 style-loader

webpack.config.js

``` js
module.exports = {
    module: {
        rules: [
            { test: /\.css$/, use: ['style-loader', 'css-loader' }
        ]
    }
};
```
复制代码

配置 loader

rules 配置模块的读取和解析规则,一般用来配置 Loader。其类型是一个数组,数组里每一项都描述了如何去处理部分文件。 配置一项 rules 时大体经过如下方式:

  • 条件匹配:经过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件

  • 应用规则:对选中后的文件经过 use 配置项来应用 Loader,能够只应用一个 Loader 或者按照从后往前的顺序应用一组 Loader,同时还能够分别给 Loader 传入参数

  • 重置顺序:一组 Loader 的执行顺序默认是从右到左(从下到上、从后到前)执行,经过 enforce 选项可让其中一个 Loader 的执行顺序放到最前或者最后

  • 在 Loader 须要传入不少参数时,你还能够经过一个 Object 来描述

  • test include exclude 这三个命中文件的配置项能够传入一个字符串或正则,其实它们还都支持数组类型

具体使用:

module.exports = {
    module: {
        rules: [
            
             {
                // 命中 JavaScript 文件
                test: [
                    /\.js?$/,
                    /\.jsx?$/
                ],
                // 用 babel-loader 转换 JavaScript 文件
                // ?cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 编译结果加快从新编译速度
                use: [
                    {
                        loader:'babel-loader',
                        options:{
                            cacheDirectory:true,
                        },
                        // enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
                        // enforce 的值还能够是 pre,表明把 Loader 的执行顺序放到最前面
                        enforce:'post'
                    }
                ],
                // 只命中src目录里的js文件,加快 Webpack 搜索速度
                include: path.resolve(__dirname, 'src')
            },
            {
                // 命中 SCSS 文件
                test: /\.scss$/,
                // 使用一组 Loader 去处理 SCSS 文件。
                // 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。
                use: ['style-loader', 'css-loader', 'sass-loader'],
                // 排除 node_modules 目录下的文件
                exclude: path.resolve(__dirname, 'node_modules')
            }
        ]
    }
};
复制代码

plugins

Plugin 是用来扩展 Webpack 功能的,经过在构建流程里注入钩子实现,它给 Webpack 带来了很大的灵活性。

基本使用

好比每次打包文件到 dist 文件夹下,就可能致使文件夹下面的文件过多,内容过大,那么此时咱们可能须要在打包以前先将 dist 文件下的文件都删除掉,可是每次都手动删除岂不是太麻烦,此时咱们就可使用 clean-webpack-plugin 插件来帮助咱们清理 dist 文件夹

插件安装

npm install clean-webpack-plugin --save-dev
复制代码

webpack.config.js

const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    plugins: [
        new CleanWebpackPlugin(['dist'])
    ]
}
复制代码

其余概念术语

资源(Asset)

这是一个广泛的术语,用于图片、字体、媒体,还有一些其余类型的文件,经常使用在网站和其余应用程序。这些文件一般最终在输出(output ) 中成为单个文件,但也能够经过一些东西内联,像 style-loader 或者 url-loader 。

Bundle

由多个不一样的模块生成,bundles 包含了早已通过加载和编译的最终源文件版本。

Chunk

这是 webpack 特定的术语被用在内部来管理 building 过程。bundle 由 chunk 组成,其中有几种类型(例如,入口 chunk(entry chunk) 和子 chunk(child chunk))。一般 chunk 会直接对应所输出的 bundle,可是有一些配置并不会产生一对一的关系。

依赖关系图(Dependency Graph)

有时候一个文件依赖于其余文件,webpack 将其视为依赖关系(dependency)。从一个或多个入口点开始,webpack 递归构建一个依赖关系图,里面包含了你的应用程序须要的全部模块/资源(mudule/asset)。

模块(Module)

提供比完整程序接触面(surface area)更小的离散功能块。精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每一个模块都具备条理清楚的设计和明确的目的。

  • 模块解析(Module Resolution):一个模块能够做为另外一个模块的依赖模块,resolver 是一个库( library )用于帮助找到模块的绝对路径... 模块将在 resolve.modules 中指定的全部目录内搜索。

Tree Shaking

移除未使用/多余的代码,或者更准确地说,只导入引用的代码。编译器(compiler)(例如 webpack)将经过分析各类 import 语句和引入代码的使用状况,来肯定哪些部分的依赖关系被实际使用,删除不是“树”的部分,以实现此功能

第三方库入口点(Vendor Entry Point)

从 app.js 和 vendors.js 开始建立依赖图(dependency graph)。这些依赖图是彼此彻底分离、互相独立的,容许你使用 CommonsChunkPlugin 从「应用程序 bundle」中提取 vendor 引用(vendor reference) 到 vendor bundle。能够帮助你在 webpack 中实现被称为长效缓存的通用模式。

优化

  • Bundle 分离(Bundle Splitting) 这个流程提供一个优化 build 的方法,容许 webpack 为应用程序生成多个 bundle。最终效果是,当其余某些 bundle 的改动时,彼此独立的另外一些 bundle 均可以不受到影响,减小须要从新发布的代码量,所以由客户端从新下载并利用浏览器缓存。

  • 代码分离(Code Splitting) 指将代码分离到每一个 bundles/chunks 里面,你能够按需加载,而不是加载一个包含所有的 bundle。


总结

本文简单介绍了一下 Webpack 的做用以及 Webpack 核心概念的用法。想了解更多的朋友能够参考个人下一篇文章:从零开始搭建一个 Webpack 开发环境配置(附 Demo)

相关文章
相关标签/搜索