在前端开发中,经常会遇到多个模块之间需要共享的代码或库,如果每个模块都将这些共享的代码复制到自己的模块中,会造成代码冗余和维护成本的增加。为了解决这个问题,我们可以使用 webpack 的功能来抽离公共模块,从而减小打包后的代码体积和加快页面加载速度。
在 webpack3 中,我们可以使用 CommonsChunkPlugin 来手动配置抽离公共模块,但是在 webpack4 中,这个插件已经被废弃,webpack 推荐使用其他方式来实现公共模块的抽离。
本文将介绍 webpack4 中用于替代 CommonsChunkPlugin 的两种方式:optimization.splitChunks 和 optimization.runtimeChunk,同时会提供详细的使用示例和说明。
optimization.splitChunks
optimization.splitChunks 是 webpack4 中用于抽离公共模块的默认配置项,我们可以在 webpack 配置文件中对其进行配置。
// webpack.config.js module.exports = { optimization: { splitChunks: { chunks: 'all' } } }
配置项说明:
- chunks: 需要抽离公共模块的模块类型,可选值为 all、async 和 initial,默认值为 async。all 表示所有模块都要参与公共模块的抽离,async 表示只抽离异步加载的模块(使用 import() 或 require.ensure),initial 表示只抽离同步加载的模块(默认情况下所有入口模块都是同步加载的);
除了 chunks,splitChunks 还支持其他配置项,比如 minSize、maxSize、minChunks、maxAsyncRequests、maxInitialRequests 等,这些配置项的作用和 CommonsChunkPlugin 中的配置项类似,可以根据实际情况进行配置。
使用示例:
-- -------------------- ---- ------- -- -------- ------ ------ ---- -------- ------ ------ ---- -------- ------------------- ------- -- ---- ------ ------ ---- -------- ------------------- -- ---- ------ ------ ---- -------- -------------------展开代码
以上是三个入口模块,其中 index.js 引用了 jquery 和 lodash,a.js 和 b.js 分别引用了 lodash 和 jquery。
在没有配置 optimization.splitChunks 的情况下,打包后的代码如下:
Asset Size Chunks Chunk Names main.js 695 bytes main, 0 [emitted] main
可以看到,打包后的代码只有一个 main.js 文件,包含了所有模块的代码。这样会导致代码冗余和页面加载速度慢。
现在我们对 optimization.splitChunks 进行配置:
module.exports = { optimization: { splitChunks: { chunks: 'all' } } }
重新打包后,代码变成了如下两个文件:
Asset Size Chunks Chunk Names vendors~a~b~main.0a2f2ff.js 9.31 KiB vendors~a~b~main [emitted] vendors~a~b~main main.js 746 bytes main [emitted] main
可以看到,代码分成了两个文件:vendors<del>a</del>b<del>main.0a2f2ff.js 和 main.js。其中 vendors</del>a<del>b</del>main.0a2f2ff.js 包含了所有模块的共享代码,而 main.js 只包含了 index.js 中的代码。
optimization.runtimeChunk
optimization.runtimeChunk 是另一种用于抽离公共模块的配置项,它用于将 webpack 运行时代码从 bundles 中提取出来。这是为了解决在多个入口模块中使用相同的库时,代码会出现重复的问题。
使用示例:
module.exports = { optimization: { runtimeChunk: { name: entrypoint => `runtime~${entrypoint.name}` } } }
以上代码配置了 optimization.runtimeChunk,它会将 webpack 运行时代码提取到 runtime~[entrypoint.name].js 文件中。
在 entry 属性中添加多个入口模块:
-- -------------------- ---- ------- -------------- - - ------ - ------ ----------------- -- ------------- -- ------------ -- ------------- - ------------- - ----- ---------- -- ---------------------------- - - -展开代码
重新打包后,代码变成了如下三个文件:
Asset Size Chunks Chunk Names runtime~index.js 6.28 KiB runtime~index [emitted] runtime~index runtime~a.js 6.28 KiB runtime~a [emitted] runtime~a runtime~b.js 6.28 KiB runtime~b [emitted] runtime~b vendors~a~b~index.fa8d08a9.js 9.33 KiB vendors~a~b [emitted] [big] vendors~a~b~index index.js 740 bytes index [emitted] index a.js 108 bytes a [emitted] a b.js 99 bytes b [emitted] b
可以看到,webpack 运行时代码被抽取到了 runtime~[entrypoint.name].js 文件中。当多个入口模块同时使用相同的库时,这些模块中的代码不再重复,而是使用了公共的 webpack 运行时代码。
总结
在 webpack4 中,推荐使用 optimization.splitChunks 和 optimization.runtimeChunk 来抽离公共模块,代替了 CommonsChunkPlugin 插件。优化代码体积和加快页面加载速度,记录这个小小的进步,为在前端开发上更进一步提升了技术。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f28a08f6b2d6eab3c2d407