babel缓存
babel解析js是非常耗时的,想象一下,假如我们有100个js文件,某一时刻只修改了其中一个,构建的时候还是会对这100个文件进行解析,这显然是不够高效的。这时候我们可以给babel加一个缓存,再次构建时,对那些没有发生修改的js文件,直接从缓存中读取解析结果而不需要重新解析。
好了,我们在babel-loader中添加一个cacheDirectory参数配置
//.babelrc
{
"presets": [
"@babel/env",
"@babel/react"
],
"cacheDirectory": true,
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3
}
]
]
}
文件资源缓存
webpack提供了hash,chunkhash,contenthash实现文件资源缓存,我们就这三种缓存机制和使用场景说一下。
当我们在浏览器中对一个文件资源发起请求后,服务端返回资源文件,如果响应头中包含了对资源的缓存信息时,浏览器会对该资源进行缓存,当我们再次请求相同文件资源时,浏览器不会向服务器发起请求,而是直接返回缓存中的资源
hash
那么有人就会说了,改变资源名称或者版本不就可以重新请求了。是的,webpack 的 hash 就可以为我们做到每次打包生成不同的hash值。如:
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: '[name].[hash:6].js', //给文件名添加hash值
path: path.resolve(__dirname, 'dist'),
chunkFilename: '[name].[hash:6].js'
}
}
这样 yarn build 打包后文件名都会形如 **.36361b.js,包含一个hash值。当浏览器再次请求资源时,发现资源名字变了,于是重新向服务器请求。
但是,这样也有一个问题,webpack hash 每次打包,所有资源文件的hash值都是一样的,也就是说所有文件资源的缓存都失效了,都要再次向服务器请求。这显然是不合理的,我们只想向服务器请求那些修改了的文件资源
chunkhash
那我们是不是可以用chunkhash来解决这个问题呢?首先我们要明白webpack中chunk的概念——有依赖关系的文件资源都视为一个chunk。对于spa来说,只有一个入口,所有文件资源都直接或间接和入口文件有依赖关系,也就是说在webpack看来,一个spa就是一个chunk,所有的文件资源公用一个hash值,还是没能解决上面的问题
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: '[name].[chunkhash:6].js', //给文件名添加chunkhash值
path: path.resolve(__dirname, 'dist'),
chunkFilename: '[name].[chunkhash:6].js'
}
}
但chunkhash也不是完全无用武之地,多页面打包的时候,不同的入口属于不同的chunk,还是可以使用chunkhash的
contenthash
webpack打包时,根据不同的文件生成不同的contenthash值,哎,这好像恰好可以解决上面公用hash值的问题
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: '[name].[contenthash:6].js', //给文件名添加chunkhash值
path: path.resolve(__dirname, 'dist'),
chunkFilename: '[name].[contenthash:6].js'
}
}
这样两次打包前后,只有发生修改的文件资源hash值会发生改变,没有修改的文件资源hash值不会变,浏览器依然可以从缓存中拿未发生改变的资源,只需要向服务器请求内容发生改变的资源
总结
- babel缓存时从构建的角度去提升开发效率;
- webpack hash是从前端页面性能角度去提升用户体验;