浅谈如何使用 webpack 优化资源(5)

运行打包可以看到:

Hash: 34a71fcfd9a24e810c21
Version: webpack 3.6.0
Time: 9618ms
     Asset   Size Chunks          Chunk Names
0.2c65.child.js 5.82 kB    0 [emitted]
1.6e26.child.js  4.4 kB    1 [emitted]
2.e4bc.child.js   3 kB    2 [emitted]
 index.4e2f.js 64.2 kB    3 [emitted]     index
 vendor.5fd1.js  276 kB    4 [emitted] [big] vendor

可以看到 `vendor` 被单独打包出来了。

当我们改变业务代码时再次打包:

Hash: cd3f1bc16b28ac97e20a
Version: webpack 3.6.0
Time: 9750ms
     Asset   Size Chunks          Chunk Names
0.2c65.child.js 5.82 kB    0 [emitted]
1.6e26.child.js  4.4 kB    1 [emitted]
2.e4bc.child.js   3 kB    2 [emitted]
 index.4d45.js 64.2 kB    3 [emitted]     index
 vendor.bc85.js  276 kB    4 [emitted] [big] vendor

vendor 包同样被打包出来的,然而它的文件 hash 却发生了变化,这显然不符合我们长缓存的需求。

这是因为 webpack 在使用 CommoChunkPlugin 的时候会生成一段 runtime 代码(它主要用来处理代码模块的映射关系),而哪怕没有改变 vendor 里的代码,这个 runtime 仍然是会跟随着打包变化的并且打入 verdor 中,所以 hash 就会开始变化了。解决方案则是把这部分的 runtime 代码也单独抽离出来,修改之前的 `CommonsChunkPlugin` 为:

// webpack.config.js
...
new webpack.optimize.CommonsChunkPlugin({
 name: ['vendor', 'runtime'],
 minChunks: Infinity,
}),
...

执行打包可以看到生成的代码中多了 `runtime` 文件,同时即使改变业务代码,vendor 的 hash 值也保持不变了。

当然这段 `runtime` 实际上非常短,我们可以直接 inline 在 html 中,如果使用的是 `html-webpack-plugin` 插件处理 html,则可以结合 [`html-webpack-inline-source-plugin`](DustinJackson/html-webpack-inline-source-plugin) 插件自动处理其 inline。

(2)公共资源抽离

在我们打包出来的 js 资源包括不同入口以及子模块的 js 资源包,然而它们之间也会重复载入相同的依赖模块或者代码,因此可以通过 CommonsChunkPlugin 插件将它们共同依赖的一些资源打包成一个公共的 js 资源。

// webpack.config.js
plugins: [
 new BundleAnalyzerPlugin(),
 new webpack.DefinePlugin({
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
 }),
 new UglifyJSPlugin({
  uglifyOptions: {
   ie8: false,
   output: {
    comments: false,
    beautify: false,
   },
   mangle: {
    keep_fnames: true
   },
   compress: {
    warnings: false,
    drop_console: true
   },
  }
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: ['vendor', 'runtime'],
  minChunks: Infinity,
 }),
 new webpack.optimize.CommonsChunkPlugin({
  // ( 公共chunk(commnons chunk) 的名称)
  name: "commons",
  // ( 公共chunk 的文件名)
  filename: "commons.[chunkhash:4].js",
  // (模块必须被 3个 入口chunk 共享)
  minChunks: 3
 })
],

      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6174.html