说明
- 这套笔记是对于
webpack 5.x进行阐述的。(webpack <= 4用法稍有不同)
打包模式
概述:
提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。
string = 'production': 'none' | 'development' | 'production'
基本使用:
用法一:在 webpack.config.js 的文件中指定 mode
const config = {
mode: 'production',
// ...
};
module.exports = config;
用法二:在终端命令中指定
webpack --mode=development
配置可选项:
| 选项 | 描述 |
|---|---|
| development | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名。 |
| production | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin 和 TerserPlugin 。 |
| none | 不使用任何默认优化选项 |
webpack 的输入输出
输入:
入口 (entry) 是 webpack 打包前必须要知道的入口文件信息, webpack 会通过entry知道项目需要打包的文件入口以及对应的 JS 模块(chunk)
通常情况下,一个页面对应一个 entry 入口。在 SPA 中我们使用 单文件入口打包,在 MPA 中我们使用 多文件入口打包
单文件入口打包:
通常情况下,单文件入口打包, 配置方式如下:
- 使用简写:
const config = {
mode: 'production',
entry: './src/index.js',
// ...
};
module.exports = config;
- 使用完整写法:
const config = {
mode: 'production',
entry: {
main: './src/index.js'
},
// ...
};
module.exports = config;
多文件入口打包:
多文件入口,我们可以使用以下的方式:
- 使用数组导入入口,模块会按照数组的顺序依次打包
const config = {
mode: 'production',
entry: ['./src/index.js', './src/detail.js'],
// ...
};
module.exports = config;
- 使用对象导入多入口(用法:
entry: { <entryChunkName> string | [string] } | {})
const config = {
mode: 'production',
entry: ['./src/index.js', './src/detail.js'],
// ...
};
module.exports = config;
注意
- 使用对象语法打包多入口时,配置出口也需要配置对应的出口
[name].js(此时不能为bundle.js)- 对象语法会比较繁琐。然而,这是应用程序中定义入口的最可扩展的方式。
配置补充
注意:
runtime和dependOn不应在同一个入口上同时使用dependOn不能是循环引用的,下面的例子也会出现错误
输出:
output 是 webpack.config.js 配置的必填项,它包括了一组选项,指示 webpack 如何去输出、以及在哪里输出你的 bundle、asset 和其他你所打包或使用 webpack 载入的任何内容。
output 的配置非常多,这里列举一些常用的配置,完整配置请参考:webpack 中文文档-output配置
本文挑一些最常用的配置来讲一下,如下图表格所示:
output.filename
output.filename 决定了每个输出 bundle 的名称。这些 bundle 将写入到 output.path 选项指定的目录下。
- 在单文件入口的打包情况下,
output.filename使用静态名称进行配置:
const config = {
// ...
output: {
filename: 'bundle.js',
// ...
},
// ...
};
module.exports = config;
- 在多文件入口的打包情况下,
output.filename使用动态名称进行配置:
const config = {
// ...
output: {
filename: '[name].bundle.js',
// ...
},
// ...
};
module.exports = config;
const config = {
// ...
output: {
filename: '[id].bundle.js',
// ...
},
// ...
};
module.exports = config;
const config = {
// ...
output: {
filename: '[contenthash].bundle.js',
// ...
},
// ...
};
module.exports = config;
const config = {
// ...
output: {
filename: '[id]-[name]-[contenthash].bundle.js',
// ...
},
// ...
};
module.exports = config;
output.path
output.path用于配置 output 目录对应一个 绝对路径(建议使用 path.resolve 或者 path.join 方法连接的路径了,直接传入相对路径会报错)。
const path = require('path');
module.exports = {
// ...
output: {
path: path.resolve(__dirname, 'dist'),
// ...
},
// ...
};
output.chunkFilename
output.chunkFilename 决定了非初始(non-initial)chunk 文件的名称。
注意:
- 和
output.filename不同,output.chunkFilname是可变的 (基于 HTTP 请求)。因此,需要在 webpack 构建时,将chunk id的值对应映射到占位符(如[name]和[chunkhash])。output.chunkFilname做完映射之后会增加文件大小,并且在任何chunk的占位符值修改后,都会使bundle失效。- 默认使用 [id].js 或从 output.filename 中推断出的值([name] 会被预先替换为 [id] 或 [id].)。
module.exports = {
//...
output: {
//...
chunkFilename: '[id].js',
},
};
module.exports = {
//...
output: {
chunkFilename: (pathData) => {
return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
},
},
};
output.asyncChunks
output.asyncChunks用于创建按需加载的异步 chunk。
module.exports = {
//...
output: {
//...
asyncChunks: true,
},
};
output.clean
output.clean用于清除之前输出在 output 下的内容。(webpack5 新增)
module.exports = {
//...
output: {
clean: true, // 在生成文件之前清空 output 目录
},
};
module.exports = {
//...
output: {
clean: {
dry: true, // 打印而不是删除应该移除的静态资源
},
},
};
// 配置方式一
module.exports = {
//...
output: {
clean: {
keep: /ignored/dir//,
},
},
};
// ------------------------------------------------------------------------------- //
// 配置方式二
module.exports = {
//...
output: {
clean: {
keep(asset) {
return asset.includes('ignored/dir');
},
},
},
};