概念

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

从 webpack v4.0.0 开始,可以不用引入一个配置文件(但是引入配置文件webpack.config.js还是很有必要的)。然而,webpack 仍然还是高度可配置的。在开始前你需要先理解四个核心概念:

  • Entry(入口文件)
  • Output(出口文件)
  • Loaders(加载器)
  • Plugins(插件)

Entry(入口文件)

入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

每个依赖项随即被处理,最后输出到称之为 bundles 的文件中

默认值为 ./src

1
2
3
4
5
const config = {
entry: {
main: './path/to/my/entry/file.js'
}
};

Output(出口文件)

The output property tells webpack where to emit the bundles it creates and how to name these files, it defaults to ./dist. Basically, the entire app structure will get compiled into the folder that you specify in the output path. You can configure this part of the process by specifying an output field in your configuration:

1
2
3
4
5
6
7
8
9
10
//webpack.config.js
const path = require('path');

module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};

Loaders(加载器)

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。

本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

在更高层面,在 webpack 的配置中 loader 有两个目标:

test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
use 属性,表示进行转换时,应该使用哪个 loader。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const path = require('path');

const config = {
output: {
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};

module.exports = config;

Plugins(插件)

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins

const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};

module.exports = config;

There are many plugins that webpack provides out of the box! Check out our list of plugins for more information.

模式(Mode)

通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

1
2
3
module.exports = {
mode: 'production'
};

模块(Modules)

在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块

每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的。

Node.js 从最一开始就支持模块化编程。然而,在 web,模块化的支持正缓慢到来。在 web 存在多种支持 JavaScript 模块化的工具,这些工具各有优势和限制。webpack 基于从这些系统获得的经验教训,并将模块的概念应用于项目中的任何文件。

什么是 webpack 模块

对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:

ES2015 import 语句
CommonJS require() 语句
AMD define 和 require 语句
css/sass/less 文件中的 @import 语句。
样式(url(…))或 HTML 文件(<img src=...>)中的图片链接(image url)

支持的模块类型

webpack 通过 loader 可以支持各种语言和预处理器编写模块。loader 描述了 webpack 如何处理 非 JavaScript(non-JavaScript) 模块,并且在bundle中引入这些依赖。 webpack 社区已经为各种流行语言和语言处理器构建了 loader,包括:

CoffeeScript
TypeScript
ESNext (Babel)
Sass
Less
Stylus
总的来说,webpack 提供了可定制的、强大和丰富的 API,允许任何技术栈使用 webpack,保持了在你的开发、测试和生成流程中无侵入性(non-opinionated)。

webpack 非配置文件 打包流程

  • 首先,全局安装 webpack npm install webpack -g 以及 webpack-cli npm install webpack-cli -g
  • 第二,本地安装 webpack 为开发依赖 npm install webpack --save-dev
  • 第三,本地安装 webpack-cli 为开发依赖 npm install webpack-cli --save-dev
  • 第四,编写模块化的代码
  • 第五,利用命令:npx webpack 进行打包

webpack 通过配置文件 打包流程

  • 首先,全局安装 webpack npm install webpack -g 以及 webpack-cli npm install webpack-cli -g
  • 第二,本地安装 webpack 为开发依赖 npm install webpack --save-dev
  • 第三,本地安装 webpack-cli 为开发依赖 npm install webpack-cli --save-dev
  • 第四,编写模块化的代码
  • 第五,编写配置文件 webpack.config.js 如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    const path = require('path');

    module.exports = {
    entry: './src/index.js',
    output: {
    filename: 'bundle2.js',
    path: path.resolve(__dirname, 'dist')
    },
    module: {
    rules:[
    {
    test: /\.css$/,
    use:[{loader:'style-loader'},{loader:'css-loader'}]
    }
    ]
    }
    };
  • 第六,利用命令:npx webpack 进行打包

  • 目录结构
    目录结构