持久化缓存

  • Improve build performance with Persistent Caching (通过使用持久性缓存来提高构建性能)

Cache基本配置

 在 Webpack 4 中,cache 只是单个属性的配置,所对应的赋值为 true 或 false,用来代表是否启用缓存,或者赋值为对象来表示在构建中使用的缓存对象。而在 Webpack 5 中,cache 配置除了原本的 true 和 false 外,还增加了许多子配置项,例如:

  • cache.type:缓存类型。值为 'memory'或‘filesystem’,分别代表基于内存的临时缓存,以及基于文件系统的持久化缓存。在选择 filesystem 的情况下,下面介绍的其他属性生效。
  • cache.cacheDirectory:缓存目录。默认目录为 node_modules/.cache/webpack。
  • cache.name:缓存名称。同时也是 cacheDirectory 中的子目录命名,默认值为 Webpack 的 ${config.name}-${config.mode}。
  • cache.cacheLocation:缓存真正的存放地址。默认使用的是上述两个属性的组合:path.resolve(cache.cacheDirectory, cache.name)。该属性在赋值情况下将忽略上面的 cacheDirectory 和 name 属性。
     

单个模块的缓存失效
Webpack 5 会跟踪每个模块的依赖项:fileDependencies、contextDependencies、missingDependencies。当模块本身或其依赖项发生变更时,Webpack 能找到所有受影响的模块,并重新进行构建处理。

这里需要注意的是,对于 node_modules 中的第三方依赖包中的模块,出于性能考虑,Webpack 不会跟踪具体模块文件的内容和修改时间,而是依据依赖包里package.json 的 name 和 version 字段来判断模块是否发生变更。因此,单纯修改 node_modules 中的模块内容,在构建时不会触发缓存的失效。

全局的缓存失效
当模块代码没有发生变化,但是构建处理过程本身发生变化时(例如升级了 Webpack 版本、修改了配置文件、改变了环境变量等),也可能对构建后的产物代码产生影响。因此在这种情况下不能复用之前缓存的数据,而需要让全局缓存失效,重新构建并生成新的缓存。在 Webpack 5 中共提供了 3 种不同维度的全局缓存失效配置。

1、buildDependencies

第一种配置是cache.buildDependencies,用于指定可能对构建过程产生影响的依赖项。

它的默认选项是{defaultWebpack: ["webpack/lib"]}。这一选项的含义是,当 node_modules 中的 Webpack 或 Webpack 的依赖项(例如 watchpack 等)发生变化时,当前的构建缓存即失效。

上述选项是默认内置的,无须写在项目配置文件中。配置文件中的 buildDenpendencies 还支持增加另一种选项 {config: [__filename]},

它的作用:(1)获取最新配置及其依赖项(2)当配置文件内容或配置文件依赖的模块文件发生变化时,当前的构建缓存即失效。
 

2、version

第二种配置是 cache.version。当配置文件和代码都没有发生变化,但是构建的外部依赖(如环境变量)发生变化时,预期的构建产物代码也可能不同。这时就可以使用 version 配置来防止在外部依赖不同的情况下混用了相同的缓存。例如,可以传入 cache: {version: process.env.NODE_ENV},达到当不同环境切换时彼此不共用缓存的效果。

3、name

缓存的名称除了作为默认的缓存目录下的子目录名称外,也起到区分缓存数据的作用。例如,可以传入 cache: {name: process.env.NODE_ENV}。这里有两点需要补充说明:

  • name 的特殊性:与 version 或 buildDependencies 等配置不同,name 在默认情况下是作为缓存的子目录名称存在的,因此可以利用 name保留多套缓存。在 name 切换时,若已存在同名称的缓存,则可以复用之前的缓存。与之相比,当其他全局配置发生变化时,会直接将之前的缓存失效,即使切换回之前已缓存过的设置,也会当作无缓存处理。
  • 当 cacheLocation 配置存在时,将忽略 name 的缓存目录功能,上述多套缓存复用的功能也将失效。

补充:

此外,在 Webpack 4 中,部分插件是默认启用缓存功能的(例如压缩代码的 Terser 插件等),项目在生产环境下构建时,可能无意识地享受缓存带来的效率提升,但是在 Webpack 5 中则不行。无论是否设置 cache 配置,Webpack 5 都将忽略各插件的缓存设置(例如 TerserWebpackPlugin),而由引擎自身提供构建各环节的缓存读写逻辑。

因此,项目在迁移到 Webpack 5 时都需要通过上面介绍的 cache 属性来单独配置缓存。

持久化缓存开启与否对比:

(1)未开启:构建时间38s左右

  cache: {
        type: 'memory'
    },

(2)开启持久化缓存:构建时间14s左右,提升了63%

    cache: {
        type: 'filesystem',
        buildDependencies: {
            config: [__filename]
        },
        name: 'dev_cache'
    },

Webpack5 内置缓存方案探索

Webpack5 内置缓存方案探索 - 掘金

webpack5会 缓存生成的webpack模块和chunk,来改善构建速度。

webpack5内置的缓存方案 = cache-loader + dll

缩短 Webpack 构建时间以及减小成本的解决方案,他们包括但不限于:

  • cache-loader
  • DllReferencePlugin
  • auto-dll-plugin
  • thread-loader
  • happypack
  • hard-source-webpack-plugin

这里简要进行说明:

1、cache-loader 可以在一些性能开销较大的 loader 之前添加,目的是将结果缓存到磁盘里;

  • 在一些性能开销较大的 loader 之前添加此 loader,以将结果缓存到磁盘里。
  • 请注意,保存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader 使用此 loader。
  • 官方提供的 cache-loader,可将上一个 loader 处理的结果缓存到磁盘上,下一次在走这个流程的时候(pitch)依据一定的规则来使用缓存内容从而跳过后面 loader 的处理。不过 cache-loader 也仅仅能覆盖到经由 loader 处理后的文件内容,缓存内容的范围比较受限,此外就是 cache-loader 缓存是在构建流程当中进行的,缓存数据的过程也是有一些性能开销的,会影响整个的编译构建速度,所以建议是搭配译耗时较长的 loader 一起使用。

  • Webpack4时之所以要有dll,是因为cache-loader并不能覆盖所有模块,只能对个别被loader处理的模块进行缓存。而那些通用的库是没法被cache-loader处理的,所以只能通过dll的方式来预编译。

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          'cache-loader',
          'babel-loader'
        ],
        include: path.resolve('src')
      }
    ]
  }
}

2、DLLPlugin 和 DLLReferencePlugin 实现了拆分 bundles,同时节约了反复构建 bundles 的成本,大大提升了构建的速度;

3、thread-loader 和 happypack 实现了单独的 worker 池,用于多进程/多线程运行 loaders;

4、vue-cli 和create-react-app 并没有使用到 dll 技术,而是使用了更好的代替者:hard-source-webpack-plugin。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值