jaychen

9 天前

webpack构建优化之减少发布文件

本文作者:IMWeb jaychen 原文出处:IMWeb社区 未经同意,禁止转载

本文作者:IMWeb json 原文出处:IMWeb社区 未经同意,禁止转载

概述

随着项目越来越大,页面增多,每次需求中修改一个页面的逻辑后,总会引起其他页面文件的hash改变,导致发布文件过多,提心吊胆的发布,而且文件hash的频繁变动,也没有办法很好利用浏览器缓存。那么有没有办法减少文件的修改呢? 下面以一个简单的例子来分析下。

项目简介

项目的目录结构如图:

整个项目采用react + webpack架构 , 页面文件放在pages下面。

构建的入口是每个页面的入口,使用CommonsChunkPlugin将项目的基础库打包到vendor中,便于做缓存,使用web-webpack-plugin组织页面文件。

感兴趣的可以访问 demo , 自己跑的试试。

下面开始分析优化带来的影响。

使用chunkhash代替hash

  • chunkhash是根据每个chunk内容计算出的hash值。只要chunk不变,hash就不变。
  • hash是compilation对象计算所得,而不是具体的项目文件计算所得,只要文件有改动,compilation就会被重新创建,整个项目构建的hash值都会更改。

以上,采用chunkhash代替hash应该是没有异议的。

去掉vendor中的runtime

运行上面的demo,结果如下 :

修改index页面, 再次跑构建,结果为:

对比可以发现,只是修改了一个页面的业务逻辑,使得vendor的hash发生了改变 , 由于每个页面文件都会引用vendor,会导致页面文件也会添加到发布list中。

分析打包后的vendor可以发现,

vendor里包含了index和home的hash信息, 这其实是使用CommonsChunkPlugin提取公共代码时,将页面的运行时信息,放到了vendor。

解决办法:

1、demo里的webpack是3.0.0,只要升级到3.11.0,就可以解决, 官方修复了这个bug。页面文件的hash信息不会被引入到运行时里面。

2、如果不想升级webpack , 可以将runtime提取出来,内联到页面中,保持vendor的hash不受影响。像下面这样使用,就可以了。

    new webpack.optimize.CommonsChunkPlugin({
      name: ['vendor', 'runtime'],
      minChunks: 5,
    });

经过以上步骤, 在页面中修改文件,不会影响到其他目录了。但这样就ok了吗?请接着看

固定moduleId

在home页面添加一个js文件,被index.js引用,增加前后构建结果如下:

可以看出在其中一个页面添加模块后,引起了所有文件的hash改变。从截图中可以看出,模块id都是数字,且由于插入进来a.js这个模块,使得原本分配好的模块id,重新按顺序分配。 模块id的变化,引起了文件hash的变化。

解决办法:

    new webpack.HashedModuleIdsPlugin({
      hashDigestLength: 10,
    }),

使用模块hash来代替模块id, 只要模块内容不变,就不会引起文件hash的改变。

固定moduleId, 构建结果如下:

可以看出,之前数字的moduleId,全部替换成了hash。

固定chunkId

上面讲了添加一个模块会引起moduleId的重新分配, 那如果是添加一个构建入口呢,会引起chunkId重新分配吗? 答案是会。 构建结果如下:

如图,新加了一个index2的页面, 可以看到红框处,chunkId和之前文件的对应关系变了,所以导致其他页面和vendor发生了更改。 解决办法:

new webpack.NamedChunksPlugin(),

使用chunk的名字来作为chunk的id, 构建结果为:

到这里优化就已经完成了。

0条评论

    您需要 注册 一个IMWeb账号或者 才能进行评论。