输出文件名Hash substitutions
一般部署前端的资源文件时,都会启用服务器的静态资源缓存。
这样用户的客户端就可以缓存应用的静态资源,后续就不再需要重复请求服务器获取静态资源文件。
从而整体提上了应用的响应速度。
不过开启服务器的静态资源缓存也有一些需要注意的地方:
如果在缓存策略中设置的失效时间过短,效果就不会特别明显。
如果设置的比较长,一旦这个应用发生了更新,重新部署过后,就没有办法及时更新到客户端。
为了解决这个问题,建议在生产环境中,在输出的文件名中添加哈希值(Hash)。
一旦资源文件发生改变,文件名称也会随之变化。
对于客户端而言,新的文件名就会发生新的请求,也就没有缓存,从而实现客户端及时更新。
这样就可以将缓存策略中的过期时间设置的非常长,而不用担心文件更新的问题。
webpack的filename
属性,和绝大多数插件的filename
属性,都支持通过占位符的方式为文件名设置hash。
不过它们支持3中hash,效果各不相同:
[hash]
:项目级别的hash- 一旦项目中有任何改动,当前打包的hash就会发生变化
[chunhash]
:chunk级别的hash- 打包时,只要是同一路的chunk,使用的hash就是一样的
- 动态导入的模块都会形成一个单独的chunk。这个chunk最终生成一个bundle(JS文件),如果配置了提取css文件,模块中引用的css也会被提取到css文件中。但它名义上仍然属于这个chunk。
- 例如:
- 通过动态导入方式会生成多个bundle,而这些JS模块中引入的css,如果被提取为css文件,使用的名称与JS模块一致,同样,它们使用的chunkhash也一样。
- 而生成的这些bundle使用的chunkhash就不一样。
- 修改一个模块的内容,只会更新这些文件的chunkhash
- 同一个chunk下的文件(js css)
- 使用了这个模块的文件(因为模块名称变化,所以这个文件中引入这个模块的路径也发生了变化,相当于被动改变)
- 相比
[hash]
,[chunkhash]
更精确一些
[contenthash]
:文件级别- 根据输出文件的内容生成的hash
- 即不同的文件拥有不同的hash
- 它影响到的只有:
- 当前模块生成的文件
- 使用这个模块的文件
- 注意:
- 如果配置了提取CSS文件,css实际上没有被包裹模块的bundle中,而是在主bundle文件的执行方法中,通过link方式注入到html中。
- 所以此时修改css文件,只会更新自己和主bundle的hash,而不会影响引入它的子模块。
[contenthash]
精确的定位到了文件级别的hash,只有当文件更新,才会更新它的文件名或路径。它最适合解决缓存问题。
hash长度默认20位,webpack允许通过在占位符用添加冒号+一个数字的方式指定hash的长度。
建议使用8位就够了:[contenthash:8]