如何使用 nx 缓存构建产物


这是一系列博文中的一篇,用来记录将我将公司的前端项目改造为 monorepo 的过程。

3 / 4 of Nx Monorepo Experience

There are only two hard things in Computer Science: cache invalidation and naming things.

Phil Karlton

nx 的缓存机制如何工作

How Caching Works 这篇文章中非常详细地说明了 nx 缓存构建结果的机制:
nx 会计算当前执行的 target 的 Hash 作为 cache key,在 target 执行完成后把构建输出(包括终端输出、构建结果文件)作为缓存内容存储起来。

通过配置 project.json 中 target 的 inputs 选项,我们可以调整能够让缓存失效的文件、环境变量,具体的配置方法可以查看这里

在编写文件 glob 模式的时候,有两个特殊的变量:

  • {projectRoot} :当前项目的根目录
  • {workspaceRoot}:nx 工作区的根目录

然而不管是在 inputs 还是 outputs 配置中,路径都是相对于 workspace root 的,所以 {workspaceRoot} 变量基本上没啥作用。

如何为项目添加构建缓存

缓存失效一直都是计算机领域的一个难题,在配置 nx 构建缓存的时候,我有以下两点建议:

  • inputs 配置应该宁滥毋缺,因为缓存不同步的严重性远大于缓存命中率低
  • outputs 配置必须不多不少,避免无关文件被错误地覆盖或者构建结果缺失

要做到上面两点需要精确地控制 inputs 跟 outputs 的文件匹配模式,这里推荐几种帮你减少工作量方法:

在拆分模块需要注意,尽量采用类似 Module Federation 或者 Webpack DLLPlugin 等机制,这种构建方式能够真正实现分模块打包。如果没有采用类似的机制,所有的模块都会在入口模块处被重新处理,所以除了入口模块之外,其他的模块没必要 minify ,这样可以加快打包速度。

共享缓存执行结果

nx 缓存默认存储在本地,独乐乐不如众乐乐,通过添加 nx-remotecache-minio,我们可以把 nx 缓存存储在任意与 S3 兼容的对象存储服务器上。如此,只要项目中的任意一位成员甚至 CI 服务器构建过某个模块,其他人都可以跳过构建直接从远程服务器拉取构建结果。

需要注意的是,nx-remotecache-minio 没有处理访问对象存储超时的情况,所以一旦遇到对象存储服务器不可用的情况,记得及时终止构建,并将 NX_CACHE_MINIO_URL 环境变量设置成一个无法解析的地址,避免构建命令卡住。

Series Navigation<< 拒绝重复劳动,自动为项目添加 target给大代码库的类型检查提速 >>
,

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

You can use markdown syntax in comment