CommonsChunkPlugin 与Dllplugin &DllReferencePlugin与SplitChunksPlugin
众所周知,以上都是分包插件。
1.CommonsChunkPlugin
大家都很常用的分包工具,原理就是:将指定的模块或者公用模块打包出来,减少主bundle文件的体积,配合缓存策略,加快应用访问速度。
如何使用?看得最多的应该是以下代码
new webpack.optimize.CommonsChunkPlugin({ // 这里的意思是将node_module中的模块抽离出来,成为vendor name: 'vendor', minChunks: function (module, count) { // any required modules inside node_modules are extracted to vendor
// 判断三个条件:有在处理的模块,并且是js文件,并且这个文件是在node_modules中 return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // // extract webpack runtime and module manifest to its own file in order to // // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ // 这里是从vendor里面把runtime 这部分代码抽离出来,名字是manifest name: 'manifest', chunks: ['vendor'] // 这个属性的意思是通过 chunk name 去选择 chunks 的来源。chunk 必须是 公共chunk 的子模块,指定source chunk,即指定从哪些chunk当中去找公共模块,省略该选项的时候,默认就是entry chunks // minChunks: Infinity // 这种写法和上面的写法效果一样,会马上生成公共chunk,但里面没有模块 }),
如上代码的注释,构建出来会发现多了vendor.js和manifest.js,其中vendor中是node_module中的三方库,manifest是基于vendor包继续抽取的公用包。
配合 HtmlWebpackPlugin 插件 我们可以自动引入对应包,但是要注意:manifest必须在vendor之前引入,毕竟前者是后者的公共部分
new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunks: ['manifest', 'vendor', 'app'], // app是入口文件 chunksSortMode: 'dependency' }),
根据以上代码,会发现如果改动了业务代码,重新构建的vendor包的hash哈希值并没有变化,说明啥,说明就可以让第三依赖库实现了用户端和服务端持久缓存,每次上线更新只要部署app.js就好了。
这是因为咱们通过
new webpack.optimize.CommonsChunkPlugin({ // 这里是从vendor里面把runtime 这部分代码抽离出来,名字是manifest name: 'manifest', chunks: ['vendor'] // 这个属性的意思是通过 chunk name 去选择 chunks 的来源。chunk 必须是 公共chunk 的子模块,指定source chunk,即指定从哪些chunk当中去找公共模块,省略该选项的时候,默认就是entry chunks // minChunks: Infinity // 这种写法和上面的写法效果一样,会马上生成公共chunk,但里面没有模块 }),
这段代码,把vendor里面的webpack运行代码抽出来了,vendor就可以理解为静态资源咯。去掉这段,你会发现改动业务代码,vendor包的hash值会变化。
但是,如果在业务代码中删除和增加三方库依赖,vendor是会变化的,所以上线更新只要部署app.js是在你不会更新依赖的前提下。但很难保证这一点,那么dll来了
2.Dllplugin &DllReferencePlugin
众所周知,也是个分包插件
详细介绍看这里 https://juejin.im/entry/598bcbc76fb9a03c5754d211
结果就是:
我们使用 webpack 内置的 DllPlugin
和 DllReferencePlugin
插件,通过这两个插件提前对这些公共模块进行独立编译,打出一个 vendor.dll.js 的包,之后在这部分代码没有改动的情况下不再对它们进行编译,所以项目平时的构建速度也会提升不少。vendor.dll.js 包独立存在,hash 不会发生变化,特别适合持久化缓存。
于是,我们的业务代码有变化时,只需要以新版号发布业务包(app.js)即可,vendor.dll.js 依然使用本地缓存。再配合上pwa,感觉瞬间就高端了呢
3.SplitChunksPlugin
众所周知,
webpack4中使用它,功能还是一样了
详情 :https://segmentfault.com/a/1190000015938570
https://github.com/webpack/webpack/tree/master/examples/common-chunk-and-vendor-chunk