本文作者:IMWeb jaychen 原文出处:IMWeb社区 未经同意,禁止转载
本文作者:IMWeb json 原文出处:IMWeb社区 未经同意,禁止转载
随着项目越来越大,页面增多,每次需求中修改一个页面的逻辑后,总会引起其他页面文件的hash改变,导致发布文件过多,提心吊胆的发布,而且文件hash的频繁变动,也没有办法很好利用浏览器缓存。那么有没有办法减少文件的修改呢? 下面以一个简单的例子来分析下。
项目的目录结构如图:
,
整个项目采用react + webpack架构 , 页面文件放在pages下面。
构建的入口是每个页面的入口,使用CommonsChunkPlugin将项目的基础库打包到vendor中,便于做缓存,使用web-webpack-plugin组织页面文件。
感兴趣的可以访问 demo , 自己跑的试试。
下面开始分析优化带来的影响。
以上,采用chunkhash代替hash应该是没有异议的。
运行上面的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了吗?请接着看
在home页面添加一个js文件,被index.js引用,增加前后构建结果如下:
可以看出在其中一个页面添加模块后,引起了所有文件的hash改变。从截图中可以看出,模块id都是数字,且由于插入进来a.js这个模块,使得原本分配好的模块id,重新按顺序分配。 模块id的变化,引起了文件hash的变化。
解决办法:
new webpack.HashedModuleIdsPlugin({
hashDigestLength: 10,
}),
使用模块hash来代替模块id, 只要模块内容不变,就不会引起文件hash的改变。
固定moduleId, 构建结果如下:
可以看出,之前数字的moduleId,全部替换成了hash。
上面讲了添加一个模块会引起moduleId的重新分配, 那如果是添加一个构建入口呢,会引起chunkId重新分配吗? 答案是会。 构建结果如下:
如图,新加了一个index2的页面, 可以看到红框处,chunkId和之前文件的对应关系变了,所以导致其他页面和vendor发生了更改。 解决办法:
new webpack.NamedChunksPlugin(),
使用chunk的名字来作为chunk的id, 构建结果为:
到这里优化就已经完成了。