Open Luin-Li opened 2 years ago
关于缓存这里不多说。本文要说的是,我们如何通过合理配置 webpack 去实现每次上线发布的静态资源 (CSS, JS, 图片) 的文件名称都是独一无二的。接下来主要回答两个问题:
hash、chunkhash 和 contenthash 的区别
在 webpack 中如何固定 chunkhash
hash模块识别码,用来处理模块之间的依赖关系。hash是跟每一次 webpack 打包的过程有关,任意增添或删减一个模块的依赖,hash值都会更改,并且全部文件都共用相同的hash值。
为什么图片也是采用hash,值却和别人不一样呢? 因为 file-loader的hash字段是这个loader自己定义的占位符,和webpack的内置hash字段并不一致。。
file-loader
chunkhash根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。只要我们不改动代码,就可以保证其哈希值不会受影响。
但是要保证chunkhash值在相关代码不变动的情况下也不变,还要做以下的事情:
chunkhash
optimization: { runtimeChunk: { name: 'manifest' } }
development
optimization: { namedModules: true }
生产环境使用全路径是有点太长所以可以使用 HashedModuleIdsPlugin 插件来根据路径生成的 hash。
HashedModuleIdsPlugin
如上代码块,我们不改变 a.js 和 b.js 内的代码,只是调换两者引入的顺序,如果没有设置 namedModules, a.js 和 b.js的 chunkhash 值都会改变,打包效果对比如下图:
a.js
b.js
namedModules
optimization: { namedChunks: true // 默认情况下,开发环境为 true,生产环境为 false }
chunkId 与 moduleId 的区别 - 总结
Tips [chunkhash:8]类似这种写法是截取hash值的前8位,在生产环境不要这么做!!要取完整值[chunkhash]。
[chunkhash:8]
[chunkhash]
这里有点小困惑,为什么默认情况下,开发环境为 true,生产环境为 false? 贴出git的解答。
简单来说就是固定chunkId会导致:1)打包大小增加一点点;2)chuck名暴露
在webpack@3中如果js和css文件都采用chunkhash,css文件改变,chunkhash值不会改变。只有js文件改变,chunkhash值才会改变。而在webpack@4中,不管是css文件还是js文件改变,chunkhash值都会改变。
webpack@3
webpack@4
但这都不是我们想要的结果,所以css文件的hash值应该采用contenthash,以区分 CSS 文件和 JS 文件的更新。
contenthash
contenthash根据当前文件的内容,来计算hash值。
那js文件可以用contenthash吗?可以,webpack 4.3+后。因为contenthash一开始只是被一些例如extract-text-webpack-plugin的插件使用,但是webpack 4.3+后,webpack自身也支持了。
webpack 4.3+
extract-text-webpack-plugin
生成稳定的hash文件名(图片、字体等资源使用hash或contenthash, js资源使用chunkhash,css资源使用contenthash)
hash
提取 webpack 的 runtime 代码
固定moduleId和chunkId
moduleId
chunkId
开发环境optimization.chunkIds 会被设置成 named,但当在生产环境中时,它会被设置成 deterministic, 有利于长缓存。固定 chunkId 不再需要使用 import(/* webpackChunkName: "name" */ "module") ,从而避免在生产环境 chuck 名暴露。
optimization.chunkIds
named
deterministic
import(/* webpackChunkName: "name" */ "module")
开发环境optimization.moduleIds 会被设置成 named,但当在生产环境中时,它会被设置成 deterministic。
optimization.moduleIds
Webpack 4 如何优雅打包缓存文件
webpack 学习笔记之十一 hash chunkhash contenthash
优化(Optimization)
关于缓存这里不多说。本文要说的是,我们如何通过合理配置 webpack 去实现每次上线发布的静态资源 (CSS, JS, 图片) 的文件名称都是独一无二的。接下来主要回答两个问题:
hash、chunkhash 和 contenthash 的区别
在 webpack 中如何固定 chunkhash
hash
hash模块识别码,用来处理模块之间的依赖关系。hash是跟每一次 webpack 打包的过程有关,任意增添或删减一个模块的依赖,hash值都会更改,并且全部文件都共用相同的hash值。
为什么图片也是采用hash,值却和别人不一样呢? 因为
file-loader
的hash字段是这个loader自己定义的占位符,和webpack的内置hash字段并不一致。。chunkhash
chunkhash根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。只要我们不改动代码,就可以保证其哈希值不会受影响。
但是要保证chunkhash值在相关代码不变动的情况下也不变,还要做以下的事情:
chunkhash
值也会改变,所以需要提取这部分代码即:development
下默认采用路径的方式:生产环境使用全路径是有点太长所以可以使用
HashedModuleIdsPlugin
插件来根据路径生成的 hash。如上代码块,我们不改变
a.js
和b.js
内的代码,只是调换两者引入的顺序,如果没有设置namedModules
,a.js
和b.js
的 chunkhash 值都会改变,打包效果对比如下图:chunkId 与 moduleId 的区别 - 总结
Tips
[chunkhash:8]
类似这种写法是截取hash值的前8位,在生产环境不要这么做!!要取完整值[chunkhash]
。这里有点小困惑,为什么默认情况下,开发环境为 true,生产环境为 false? 贴出git的解答。
简单来说就是固定chunkId会导致:1)打包大小增加一点点;2)chuck名暴露
在
webpack@3
中如果js和css文件都采用chunkhash
,css文件改变,chunkhash
值不会改变。只有js文件改变,chunkhash
值才会改变。而在webpack@4
中,不管是css文件还是js文件改变,chunkhash
值都会改变。但这都不是我们想要的结果,所以css文件的hash值应该采用
contenthash
,以区分 CSS 文件和 JS 文件的更新。contenthash
contenthash根据当前文件的内容,来计算hash值。
那js文件可以用contenthash吗?可以,
webpack 4.3+
后。因为contenthash
一开始只是被一些例如extract-text-webpack-plugin
的插件使用,但是webpack 4.3+
后,webpack自身也支持了。总结:用webpack实现持久化缓存
生成稳定的hash文件名(图片、字体等资源使用
hash
或contenthash
, js资源使用chunkhash
,css资源使用contenthash
)提取 webpack 的 runtime 代码
固定
moduleId
和chunkId
webpack5
chunkIds
开发环境
optimization.chunkIds
会被设置成named
,但当在生产环境中时,它会被设置成deterministic
, 有利于长缓存。固定 chunkId 不再需要使用import(/* webpackChunkName: "name" */ "module")
,从而避免在生产环境 chuck 名暴露。moduleIds
开发环境
optimization.moduleIds
会被设置成named
,但当在生产环境中时,它会被设置成deterministic
。Webpack 4 如何优雅打包缓存文件
webpack 学习笔记之十一 hash chunkhash contenthash
优化(Optimization)