Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
T treasure
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 12
    • Issues 12
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • External wiki
    • External wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • FE
  • treasure
  • Issues
  • #138

Closed
Open
Created Mar 12, 2023 by liuyajun@liuyajunMaintainer

webpack5 持久化缓存

webpack5 持久化缓存

背景

  1. 为什么 react 新项目启动这么快?如
  • linhuibaEnterExit 进撤场
  • resource-service-web 资源服务
  1. 为什么有时候修改代码、升级依赖不生效

原因

开启了 webpack5 的新特性-持久化缓存。 缓存文件至 node_modules/.cache,如果需要清除缓存,删除该文件。

项目内的 cache 的配置

webpack5 默认不开启,项目内的脚手架内部配置了开启,配置如下

  • linhuibaEnterExit 进撤场项目
cache: {
  type: 'filesystem',
  version: '75976c3e8e6750af72d5fdc2c8f5f52d',
  cacheDirectory: 'xx/linhuibaEnterExit/node_modules/.cache',
  store: 'pack',
  buildDependencies: {
    defaultWebpack: [ 'webpack/lib/' ],
    config: [
      'xx/linhuibaEnterExit/node_modules/react-scripts/config/webpack.config.js'
    ],
    tsconfig: [ 'xx/linhuibaEnterExit/tsconfig.json' ]
  }
}
  • resource-service-web 资源服务
cache: {
  type: 'filesystem',
  version: '56e655ab29e15739b04e5da711108e4f',
  cacheDirectory: 'xx/resource-service-web/node_modules/.cache',
  store: 'pack',
  buildDependencies: {
    defaultWebpack: ['webpack/lib/'],
    config: [
      'xx/resource-service-web/node_modules/react-scripts/config/webpack.config.js'
    ],
    tsconfig: ['xx/resource-service-web/tsconfig.json']
  }
}

内存缓存和文件缓存

  • memory 内存缓存 webpack4 的缓存是内存缓存,即将构建结果缓存到内存中,当进行热更新时,从内容中读取缓存,所以响应速度快;但是每次项目重新启动时,就需要在内容重新创建缓存。
  • filesystem 文件缓存(持久化缓存) webpack5 可以将构建结果持久化缓存到本地的磁盘,二次构建(非 watch 模块)直接利用磁盘缓存的结果从而跳过构建过程当中的 resolve、build 等耗时的流程,从而大大提升编译构建的效率。

持久化缓存

持久化缓存介绍文档

持久化缓存主要解决的就是优化编译流程,减少编译耗时的问题,通过全新的缓存系统的设计使得整个构建流程更加的高效和安全。

默认情况下不启用持久缓存,必须选择使用。(因为 webpack 希望用户了解这个功能开启后带来的优缺点,再自行决策是否开启。)

因为 webpack 试图将安全性置于性能之上。我们不希望默认启用一项功能,该功能会将您的性能提高 95%,但会破坏您的应用程序/工作流程/构建 5%。

缓存失效

比如 某个缓存的目标文件(如 magic.js)进行了修改,webpack 需要匹配到 magic.js ,识别存在差异,然后将缓存文件失效,再重建缓存;但也有可能匹配失败,此时就需要人为进行干预了。这部分就属于 5%。

webpack 还可能存在缓存失效的场景:

  • 当 npm 升级加载器或插件时
  • 当更改配置时
  • 当更改正在配置中读取的文件时
  • 当 npm 升级配置中使用的依赖项时
  • 当将不同的命令行参数传递给构建脚本时
  • 当有自定义构建脚本并更改它时

构建依赖项、版本和名称

为了处理构建的这些“依赖关系”,webpack 提供了三个新工具:

  • cache.buildDependencies 构建依赖
cache.buildDependencies: {
    defaultWebpack: ["webpack/lib/"]
}

cache.buildDependencies: {
    config: [__filename]
}
  • cache.version 版本,传递不同的字符串将使持久缓存失效
cache: {
    version: `${process.env.GIT_REV}`
}
  • cache.name 名称,用作持久换成文件的文件名,如 --env.target mobile|desktop 参数为移动或桌面用户创建构建
cache: {
    name: `${env.target}`
}

快照类型

和持久化缓存另外一个相关的配置是:snapshot。

snapshot 相关的配置决定了缓存内存生成 snapshot 时所采用的策略(timestamps | content hash | timestamps + content hash),而这个策略最终会影响到缓存是否失效,即 webpack 是否决定来使用缓存。

const path = require('path')
module.exports = {
  // ...
  snapshot: {
    // 针对包管理器维护存放的路径,如果相关依赖命中了这些路径,那么他们在创建 snapshot 的过程当中不会将 timestamps、content hash 作为 snapshot 的创建方法,而是 package 的 name + version
    // 一般为了性能方面的考虑,
    managedPaths: [path.resolve(__dirname, '../node_modules')],
    immutablePaths: [],
    // 对于 buildDependencies snapshot 的创建方式
    buildDependencies: {
      // hash: true
      timestamp: true
    },
    // 针对 module build 创建 snapshot 的方式
    module: {
      // hash: true
      timestamp: true
    },
    // 在 resolve request 的时候创建 snapshot 的方式
    resolve: {
      // hash: true
      timestamp: true
    },
    // 在 resolve buildDependencies 的时候创建 snapshot 的方式
    resolveBuildDependencies: {
      // hash: true
      timestamp: true
    }
  }
}

webpack4 持久化缓存

webpack4 可使用 hard-source-webpack-plugin,它就是基于上述 wbpack5 的实现思路的一个插件。

Webpack5 内置缓存方案探索

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); // 编译缓存

  // 如果无法编译,删除 node_modules/.cache 文件夹
  webpackConfig.plugins.push(new HardSourceWebpackPlugin({
    configHash: 'development',
  }));

官方文档

  • 缓存配置
  • snapshot 官方文档-配置
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking