runtimeChunk是什么?
webpack在打包的过程会生成runtime和manifest
代码。runtime和manifest
,在webpack配置中统一通过optimization.runtimeChunk
配置。
runtime
:在浏览器运行过程中,webpack用来连接模块之间的代码。比如,已经加载到浏览器中的连接模块逻辑、尚未加载模块的延迟加载逻辑。
manifest
:是一个json / json文件,它包含了每个模块的唯一标识符 (模块id) ,以及模块对应的文件在输出目录中的位置 之间的映射关系,用于帮助webpack快速地查找、加载所需的模块。
默认情况下,runtime和manifest
并不会打包成单独的代码块。而嵌入在入口chunk中。在umi项目中,它就是在嵌入在umi.js中。
为什么要配置optimization.runtimeChunk?
先简要地概括下,在umi项目开启了dynamicImport
时,通过配置optimization.runtimeChunk
把runtime和manifest
抽离成单独的代码块,对应用的缓存效率有帮助。
具体细节,请看以下分析:
默认配置打包存在的问题
- 未配置
optimization.runtimeChunk
,默认webpack配置的打包结果:
可以看到,除了umi.js和vendors.js以外,就是各个页面各自打包生成的文件。在此,我们以p_Solutions_edit这个页面为例,只需要关注umi.js 和p_Solutions_edit.js。
- 现在,我们对p_Solutions_edit页面进行一些修改,比如添加一个
console.log('test')
并重新打包,打包结果如下:
我们惊讶地发现,除了p_Solutions_edit.js 的hash更新了以外,umi.js的hash竟然也发生了更新。
这意味着,每当我们改动任何一个页面中的一丁点代码,并将其发布上线之后,用户打开页面不仅需要重新下载该页面对应的js文件,还需要重新下载整个umi.js文件。
这对于用户实际上是没有必要的,因为umi.js 只包含了antd等node_modules目录下的依赖和项目代码中一些公共目录的代码。这些依赖和代码并没有改动,完全可以直接使用用户之前缓存的umi.js (如果用户非首次访问的话)。
而且,一般umi.js 都比较大,我自己的项目里,打包且压缩后的umi.js有接近1MB。
为什么umi.js的hash值也会更新?
其实,umi.js 的hash发生更新的罪魁祸首就是我们之前说的runtime和manifest
。默认情况下,它俩就嵌入在umi.js 里。它们保存着本次打包生成的所有文件的路径,当然路径里也包含文件的hash。所以,一旦p_Solutions_edit页面的代码有更新,打包生成的p_Solutions_edit.js的hash更新,runtime和manifest就也要更新。
所以才导致了我们明明没有改动umi.js相关的代码,它的hash却发生了更新。
举个栗子:第二次打包生成的umi.js中保存的文件hash:
如何避免umi.js不必要的更新?
其实也简单,我们如果可以把runtime和manifest
提取成单独的代码块,不要嵌入在umi.js里,不就可以了么?
那么如何实现从入口chunk中抽离runtime和manifest呢?
在单页面应用中,webpack的配置,optimization.runtimeChunk: true
,可以实现抽离单独的runtime和manifest
。
请看umi具体配置:
javascript
chunks: ['runtime~umi', 'vendors', 'umi'], //todo
chainWebpack: function (config, { webpack }) {
config.merge({
optimization: {
minimize: process.env.NODE_ENV === 'production',
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 2,
automaticNameDelimiter: '.',
cacheGroups: {
vendors: {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: 10,
}
},
},
runtimeChunk: true //todo
},
});
},
注意:
-
请务必在
chunks
中添加'runtime~umi'
,chunks
里配置的是应用初始加载就需要的代码块,runtime和manifest
肯定需要,不然你的umi应用会一直loading,打不开页面。 -
splitChunks
是我自己的配置,如果不需要拆包,可以不配。没有splitChunks
的话,记得删掉chunks
数组里的vendors
。
验证效果
- 添加以上配置之后,我们先打一次包,本次打包结果如下:
可以看到,本次打包比以往多了一个文件,runtime~umi.[hash].js,这就是我们抽离出的单独的runtime和manifest。
- 修改p_Solutions_edit页面,再次打包,请对比umi.js 和p_Solutions_edit.js的hash:
可以看出umi.js 的hash保持没变,只有p_Solutions_edit.js 的hash有更新。runtime~umi.js的hash也会更新。
这样,就避免了代码发布后,用户再次打开页面,需要重新下载umi.js的问题,可以直接使用缓存的资源文件,以提升加载页面的速度。
如果这篇博客对你有帮助,麻烦点个赞~