04-资源缓存

116 阅读3分钟

资源缓存

webpack为了更加高效的打包,认为一些没有变动的内容不要再次打包了,因此可以在一些输出启动模板字符串(Template strings)使用contenthash

let output = {
  ...output,
  filename: '[name][contenthash].js',
  clean: false, // 注意这非常重要
}

这样做,如果打包的资源没有发生变化就不需要重新打包资源,节省了webpack打包时间和性能。但是会有个问题,A、B模块之间引用,模块A发生变化,那么它的contenthash和文件名发生变化,但是B引入了A,B没有发生变化,B没有重新打包,那么B的导入是的模块名称就失效了(还是之前的A的contenthash)。

解决办法是将runtimeChunk单独打包出来,每次生成新的runtimeChunk。

const optimization = {
  runtimeChunk: '', // runtimeChunk 单独打包的配置
}

需要注意,不要滥用contenthash这些占位符,每次运算contenthash也需要时间

SplitChunksPlugin

SplitChunksPlugin

它的作用就像名字一样,分割chunks,为什么在这里讲它,明明是《资源缓存》篇。

场景:第三方的插件比如lodash,一般在开发中基本不改变,因此可以把所有的插件打包成一个文件,在每次打包的时候就可以重复使用而不用重新打包和下载:

const optimization = {
  splitChunks: {
    // chunks: 'all' ---
    cacheGroups: { // 缓存项
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        // 把使用到的第三方的包都打包到vendors这个chunk里
        name: 'vendors',
        chunks: 'all'
      }
    }
  }
}

optimization.splitChunks的配置选项

开箱即用SplitChunksPlugin应该适用于大多数用户。 默认情况下,它只影响按需块,因为更改初始块会影响 HTML 文件应包含以运行项目的脚本标记。 Webpack 将根据这些条件自动拆分块:

  • 可以共享新块或模块来自node_modules文件夹
  • 新块将大于 20kb(在 min+gz 之前),其实是权衡 请求数量和请求数据量
  • 按需加载块时的最大并行请求数将低于或等于 30
  • 初始页面加载时的最大并行请求数将低于或等于 30

当试图满足最后两个条件时,首选更大的块

当然要用户可以更加细致化的定义改如何的去split:

  • optimization.splitChunks.chunks:

    • async:只提取异步加载的模块出来打包到一个文件中
    • initial:提取同步加载和异步加载模块,如果xxx在项目中异步加载了,也同步加载了,那么xxx这个模块会被提取两次,分别打包到不同的文件中
    • all:不管异步加载还是同步加载的模块都提取出来,打包到一个文件中
  • splitChunks.maxInitialRequests 初始页面加载时的最大并行请求数 ,默认为30

  • splitChunks.maxAsyncRequests 按需加载块时的最大并行请求,默认为30

  • splitChunks.minSize 在 min + gz 之前,最小的块必须为多少,默认 20000b

  • splitChunks.minChunks 在拆分这个模块之前判断,这个模块是不是被共享最少 minChunks 次,才允许拆分

  • splitChunks.cacheGroups,代码分割缓存组:它是一个对象,key为打包成缓存的chunk名,value为split配置:

    • priority:number,当前 cacheChunk 的分割优先级(注意上面有maxAsyncRequests、maxInitialRequests等限制,因此会选取优先级高的进行分割)
    • reuseExistingChunk:true,如果当前块包含已经从主包中分离出来的模块,它将被重用,而不是生成一个新的
    • type 缓存分组
    • test:控制此缓存组选择哪些模块。省略它会选择所有模块。它可以匹配绝对模块资源路径或块名称。当块名称匹配时,块中的所有模块都会被选中
    • name 生成的chunk的名字
    • enforce 强制的(忽略minSize,minChunks)
    • ...splitChunks,cacheGroup的配置项能够继承 和 覆盖的 splitChunks属性(相当于splitChunks的属性是cacheGroups配置项所有的默认配置)

splitChunks的cacheGroups 非常强大,能把匹配到的的所有 文件打包到一起进行缓存,并且打包的时候还可以分割。