核心概念
本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具 。当 webpack 处理应用程序时,它会在内部从一个或多个入口点 构建一个 依赖图(dependency graph),然后将项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示内容。
入口(entry)
入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
默认值是 ./src/index.js
,但可以通过在 webpack configuration 中配置 entry
属性,来指定一个(或多个)不同的入口起点。例如:
webpack.config.js
js
module.exports = {
entry: './path/to/my/entry/file.js',
// 是以下形式的简写:
entry: {
main: './path/to/my/entry/file.js',
},
};
在 webpack 配置中有多种方式定义 entry
属性。
-
单个入口(简写)语法
- 用法:
entry: string | [string]
- 用法:
-
对象语法
- 用法:
entry: { string | [string] } | {}
- 用法:
可以将一个文件路径数组传递给 entry
属性,这将创建一个所谓的 "multi-main entry"。在想要一次注入多个依赖文件,并且将它们的依赖关系绘制在一个 "chunk" 中时,这种方式就很有用。
webpack.config.js
javascript
module.exports = {
entry: ['./src/file_1.js', './src/file_2.js'],
output: {
filename: 'bundle.js',
},
};
当希望通过一个入口(例如一个库)为应用程序或工具快速设置 webpack 配置时,单一入口的语法方式是不错的选择。然而,使用这种语法方式来扩展或调整配置的灵活性不大。
输出(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundle ,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js
,其他生成文件默认放置在 ./dist
文件夹中。
可以通过在配置中指定一个 output
字段,来配置这些处理过程:
webpack.config.js
javascript
// Node.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',
},
};
在上面的示例中,通过 output.filename
和 output.path
属性,来告诉 webpack bundle 的名称,以及想要 bundle 生成(emit)到哪里。
可以通过配置 output
选项,告知 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个 entry
起点,但只能指定一个 output
配置。
用法
在 webpack 配置中,output
属性的最低要求是,将它的值设置为一个对象,然后为将输出文件的文件名配置为一个 output.filename
:
webpack.config.js
javascript
module.exports = {
output: {
filename: 'bundle.js',
},
};
此配置将一个单独的 bundle.js
文件输出到 dist
目录中。
多个入口起点
如果配置中创建出多于一个 "chunk"(例如,使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件),则应该使用 占位符(substitutions) 来确保每个文件具有唯一的名称。
javascript
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js',
},
output: {
filename: '[name].js',
path: __dirname + '/dist',
},
};
// 写入到硬盘:./dist/app.js, ./dist/search.js
loader
webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
webpack 的一个强大特性就是能通过 import
导入任何类型的模块(例如 .css
文件),其他打包程序或任务执行器可能并不支持。
在更高层面,在 webpack 的配置中,loader 有两个属性:
test
属性,识别出哪些文件会被转换。use
属性,定义出在进行转换时,应该使用哪个 loader。
webpack.config.js
javascript
const path = require('path');
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js',
},
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
};
以上配置中,对一个单独的 module 对象定义了 rules
属性,里面包含两个必须属性:test
和 use
。这告诉 webpack 编译器(compiler) 如下信息:
当碰到「在 require()
/import
语句中被解析为 '.txt' 的路径」时,在对它打包之前,先 use(使用) raw-loader
转换一下。
注意:
-
在 webpack 配置中定义 rules 时,要定义在
module.rules
而不是rules
中。 -
使用正则表达式匹配文件时,不要为它添加引号。也就是说,
/\.txt$/
与'/\.txt$/'
或"/\.txt$/"
不一样。前者指示 webpack 匹配任何以 .txt 结尾的文件,后者指示 webpack 匹配具有绝对路径 '.txt' 的单个文件; 这可能不符合你的意图。
loader 用于对模块的源代码进行转换。loader 可以使在 import
或 "load(加载)" 模块时预处理文件。因此,loader 类似于其他构建工具中"任务(task)",并提供了处理前端构建步骤的得力方式。
loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL。loader 甚至允许直接在 JavaScript 模块中 import
CSS 文件!
示例
例如,可以使用 loader 告诉 webpack 加载 CSS 文件,或者将 TypeScript 转为 JavaScript。为此,首先安装相对应的 loader:
bash
npm install --save-dev css-loader ts-loader
然后指示 webpack 对每个 .css
使用 css-loader
,以及对所有 .ts
文件使用 ts-loader
:
webpack.config.js
js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' },
],
},
};
插件(plugin)
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
想要使用一个插件,只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option) 自定义。也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建一个插件实例。
webpack.config.js
javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 用于访问内置插件
module.exports = {
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
在上面的示例中,html-webpack-plugin
为应用程序生成一个 HTML 文件,并自动将生成的所有 bundle 注入到此文件中。在 webpack 配置中使用插件是简单直接的。
模式(mode)
通过选择 development
, production
或 none
之中的一个,来设置 mode
参数,可以启用 webpack 内置在相应环境下的优化。其默认值为 production
。
javascript
module.exports = {
mode: 'production',
};
浏览器兼容性(browser compatibility)
Webpack 支持所有符合 ES5 标准 的浏览器(不支持 IE8 及以下版本)。webpack 的 import()
和 require.ensure()
需要 Promise
。如果想要支持旧版本浏览器,在使用这些表达式之前,还需要 提前加载 polyfill。
环境(environment)
Webpack 5 运行于 Node.js v10.13.0+ 的版本。