webpack 的第三方库分离并持久化缓存
Posted 大泽队长
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack 的第三方库分离并持久化缓存相关的知识,希望对你有一定的参考价值。
我们常常需要在浏览器缓存一些稳定的资源,如第三方库等。要达到这个目标,只需要两步:
1、提取出“稳定的资源”;
2、提供稳定的文件hash 。
处理后的出的文件就像这样子: app.1w3ad4q4.js,然后,我们设置它的缓存规则为永不过期。这样,当文件没有改动时,浏览器将一直沿用第一次下载的缓存,不会浪费流量了。
详细说明:张云龙的知乎回答
webpack中提取公共模块一般使用 webpack 内置的 CommonsChunkPlugin 插件,他可以提取出 入口chunk中 的公共模块:
1、minChunks 参数 是指 至少有minChunks个入口引用的模块才会提取出来,“infinity“ 等价于入口数量,即所有入口都引用的模块才会提取出来;
上面的例子是一个SPA,入口是main.js。为了提取出第三方库,我们新增一个vendors入口中,并引入所有用到的第三方库,就像这样:
里面并没有业务代码,vendors文件只是为了引导CommonsChunkPlugin插件提取出 第三方库。
这样,我们就能将稳定的第三方库 与 不稳定的业务代码分开缓存了!~
另:看了vue-cli的源码后,发现她是这样做的:
entry: { app: \'./src/main.js\' } ... new webpack.optimize.CommonsChunkPlugin({ name: \'vendor\', minChunks (module, count) { // 插件会遍历所有引入的模块,传入此函数的module参数,而count是当前module的引用次数 // any required modules inside node_modules are extracted to vendor return ( // 返回true则打包进vendor,否则不打包 module.resource && /\\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, \'../node_modules\') ) === 0 // 从node_module引入的返回true ) } }),
还有这种操作!!
2、names 参数 传入数组的话(names: [\'vendors\', \'manifest\']),等效于 :
文档的描述是:"
一个字符串数组被传入,这相当于插件针对每个 chunk 名被多次调用"
其中,从vendors中提取manifest 的操作,我查看vue-cli的配置,里面的注释是这样的 :
“extract webpack runtime and module manifest to its own file in order to prevent vendor hash from being updated whenever app bundle is updated”,
文档解释:
" 但是,如果我们改变应用的代码并且再次运行 webpack
,可以看到 vendor 文件的 hash 改变了。即使我们把 vendor
和 main
的 bundle 分开了,也会发现 vendor
bundle 会随着应用代码改变。这意味着我们任然无法从浏览器缓存机制中受益,因为 vendor 的 hash 在每次构建中都会改变,浏览器也必须重新加载文件。 这里的问题在于,每次构建时,webpack 生成了一些 webpack runtime 代码,用来帮助 webpack 完成其工作。当只有一个 bundle 的时候,runtime 代码驻留在其中。但是当生成多个 bundle 的时候,运行时代码被提取到了公共模块中,在这里就是 vendor
文件。为了防止这种情况,我们需要将运行时代码提取到一个单独的 manifest 文件中。尽管我们又创建了另一个 bundle,其开销也被我们在 vendor
文件的长期缓存中获得的好处所抵消。"
,大意就是,如果不把manifest(运行时代码和模块清单)提取出来,只要业务代码有改动,vendors(存放提取出来的第三方库)文件的内容也会变化,也就是它的chunkhash也会改变,这不是我们想要的!
3、hash 与 chunkhash:
[ hash ]是webpack编译的hash值,每次编译都不一样;[ chunkhash ]则是根据文件内容计算所得的hash值,文件内容不变的话,这个值是固定的。用webpack构建时,默认是css in js的,即css包含在js内,webpack计算chunkhash时,整个chunk的内容会将css的内容也计算在内。所以,不论是修改了js代码还是css代码,整个chunk的内容都改变了,计算所得的chunkhash随之改变。但理想情况下是想css或js内容改变时仅影响自身文件的chunkhash,这样客户端只需更新css 或 js文件。
要解决此问题,首先要将css单独编译输出文件,并给他一个独立的extracttextplugin插件提供的 [ contenthash ] -- 根据文本内容生成的hash值。
把css提取出来并加上hash后,就可以令css单独缓存了!
以上是关于webpack 的第三方库分离并持久化缓存的主要内容,如果未能解决你的问题,请参考以下文章