借助 wepack 的 hash
命名法,不仅可以提高我们项目的构建效率,在生产环境中,合理设置 hash
类型有助于我们对资源进行有效的缓存。
webpack hash 种类
当无情面试官问 webpack 有几种 hash 类型?
-
hash
- 工程级如果出口文件设置的类型是
hash
则每次修改任何文件,所有文件名的hash
都会跟着改变。(不能有效利用缓存) -
chunkhash
- 模块级根据不同的入口文件进行依赖文件解析、构建对应的
chunk
,生成对应的hash
值。 -
contenthash
- 文件内容级由文件内容产生的
hash
值,内容不同产生的contenthash
值也不一样。
如何设置 hash
达到项目优化的目的?
js 文件分类构建,设置 chunkhash
首先使用 CommonsChunkPlugin
插件提取第三方库和公众模块,进行单独打包构建:
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
]
接着我们在 output
对 filename
和 chunkFilename
两个字段设置 chunkhash
,生成对应 hash
值:
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'js/[name].[chunkhash].js',
chunkFilename: 'js/[id].[chunkhash].js' // chunkFilename 是处理异步模块的
},
通过设置 chunkhash
最后打包出来的 js
文件会生产三种 chunkhash
:
- 正常引入的
js
文件对应的hash
- 异步加载的
js
文件(如果在项目中存在的话)对应的hash
- 提取的三方库和公共模块对应的
hash
那么只要对应的 js
文件代码不改动,就可以保证其 chunkhash
值不会受影响,从而达到浏览器的持久缓存。
抽离 css,设置 contenthash
首先,使用 ExtractTextPlugin
插件将所有的入口 chunk
中引用的 *.css
,抽离到独立的 css
文件夹中。
抽离之后的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件当中,如果样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。
plugins: [
new ExtractTextPlugin({
filename: 'css/[name].css',
allChunks: true
}),
]
之后对 css 文件进行 contenthash
命名:
plugins: [
new ExtractTextPlugin({
filename: 'css/[name].[contenthash].css',
allChunks: true
}),
]
针对 css
文件会生产对应的 contenthash
值,只要 css
文件内容没有修改,那么 contenthash
值就一直保持不变,以有效的利用浏览器缓存。
css 文件可以设置成 chunkhash
吗?
答案是不要这么做,因为 chunkhash
是模块级,我们是将样式作为模块 import
到 js
文件中,所以它们的 chunkhash
是一致的。
即 js
和所引入的 css
共用同一个 chunkhash
,只要 js
改变,与其关联的 css
文件对应的 chunkhash
值也会改变,但可能其内容并没有改变,所以达不到缓存的效果。
这是 「性能优化小册」
系列第二篇小记,欢迎关注。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。