单独打包 runtime

什么是 runtime,如果我们为了让一个东西运行而提供的代码,就是 runtime 代码
我们为了让 main.js 能够在 IE 中运行,webpack 代码需要写额外的代码,那部分代码就是 runtime
如果不单独打包,当我们修改了配置,或者升级了,因为默认 runtime 代码是包含在 main.js 中的,所以build之后 main 的内容就会变化,导致用户就要重新下载新的文件,但是本次下载是完全没有必要的,因为 index.js 没有变化,我们只是升级了 runtime,所以必须单独打包
所以要单独打包 runtime,只要 index.js 内容没有变化(我们自己写的代码没有变化),用户就不需要重新下载这部分代码,节省用户的带宽

1
2
3
4
5
6
module.exports = {
// ...
optimzation: {
runtimeChunk: 'single',
}
}

node 依赖单独打包

比如 react、vue,如果被打包进 main.js,就会很慢,还有就是没必要,因为我们不太会去升级 react 或者 vue 版本,如果单独打包,那么用户就可以缓存下来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = {
// ...
optimization: {
// ...
splitChunks: {
cacheGroups: {
vendor: {
minSize: 0, // 如果不写 0,由于 React 文件尺寸太小,或者直接跳过
test: /[\\/]node_modules[\\/]/, // 为了匹配 /node_modules/ 或者 \node_modules\
name: 'vendors', // 文件名
chunks: 'all', // all 表示同步加载和异步加载,async 表示异步加载,initial 表示同步加载
// 这三行的整体意思就是把两种加载方式的来自 node_modules 目录的文件大包围 vendors.xxx.js
// 其中 vendors 是第三方的意思(行业默认,显得专业)
}
},
}
},
}

固定 moduleIds

因为一般来说 modules 会按照顺序进行命名
比如:1.js => 905
2.js => 403
3.js => 603
如果这个时候我把 2.js 删除了,那么可能会影响其他依赖的命名,导致用户的缓存失效,保证用户不重复下载没有变化,所以最好加上(但是不必须,一般没人这么整)

1
2
3
4
5
6
module.exports = {
// ...
optimzation: {
moduleIds: 'deterministic'
}
}

webpack 多页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
entry: {
main: './src/index.js',
admin: './src/admin.js',
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
chunks: ['main'],
}),
new HtmlWebpackPlugin({
filename: 'admin.html',
chunks: ['admin'],
}),
],
}

common chunks 共有文件(如果使用了多页面就需要使用的技巧)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = {
optimization: {
// ...
splitChunks: {
cacheGroups: {
// ...
common: {
// priority: 5,
minSize: 0,
minChunks: 2, // 同时被两处地方引用
chunks: 'all',
name: 'common',
},
},
}
},
}

无限多页面

像上面那样手写太累
用 node 读取文件在写进配置