ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

使用 Nx 配置缓存输出,正确处理 Next.js 的 `.next` 文件夹

使用 Nx 配置缓存输出,正确处理 Next.js 的 `.next` 文件夹 使用 Nx 配置缓存输出正确处理 Next.js 的.next文件夹【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nxNx 默认会识别并缓存常见的构建产物目录如dist、build但不会自动缓存 Next.js 项目根目录下的.next文件夹。本教程围绕 PNPM workspace 中的 Next.js 应用Tasker 项目讲解如何通过outputs配置精确控制 Nx 本地缓存的输出范围使next build产生的.next目录能被正确捕获、缓存并在后续任务中自动恢复从而为后续的任务管道、远程缓存与 CI 优化打下基础。读完本文你将掌握nx.json与project.json中outputs的配置语法、令牌插值规则以及 Nx 底层如何解析输出路径的原理。为什么.next默认不在缓存输出中Nx 的计算缓存系统会在任务执行前计算输入哈希执行后捕获任务产物并存入本地缓存当输入哈希未变化时直接从缓存恢复终端的输出以及任务生成的文件例如dist、build目录。Nx 自带一套“合理默认值”从源码实现看当某个 target 未显式声明outputs且不存在outputPath选项时默认捕获的路径为见 packages/nx/src/tasks-runner/utils.tsif (target build || target prepare) { return [ dist/${node.data.root}, ${node.data.root}/dist, ${node.data.root}/build, ${node.data.root}/public, ]; }也就是说Nx 只默认识别dist、build、public这类约定俗成的目录而 Next.js 的构建产物位于项目根目录的.next文件夹中并不在默认输出列表内。这导致一个实际问题next start依赖next build生成的.next目录才能运行这正是本课程第 4 课创建任务管道的前提如果.next不被缓存那么在 CI 或清理过本地缓存的机器上即使next build的结果命中缓存Nx 也无法恢复.next目录next start依然会失败。配置outputs全局与项目级两种方式要解决上述问题核心动作是在 Nx 配置中声明.next为缓存输出。Nx 支持在**全局nx.json的targetDefaults或项目级project.json/package.json的nx字段**定义outputs控制每个 target 缓存哪些文件、忽略哪些文件。方式一在nx.json中全局配置如果工作区中所有 Next.js 应用的build任务都产出.next可以在targetDefaults中统一声明// nx.json { targetDefaults: { build: { cache: true, outputs: [{projectRoot}/.next] } } }{projectRoot}会被替换为对应项目在仓库中的相对路径例如apps/web这样每个项目都会缓存自己根目录下的.next文件夹。方式二在project.json中按项目配置如果只有特定项目需要覆盖可以在项目级配置中声明在package.json的nx字段中配置的语法与之类似// apps/web/project.json { name: web, targets: { build: { cache: true, outputs: [{projectRoot}/.next] } } }结合dist输出组合配置实际项目中build任务可能同时产出dist与.next可以组合为数组// nx.json { targetDefaults: { build: { cache: true, outputs: [{workspaceRoot}/dist/{projectName}, {projectRoot}/.next] } } }注意{workspaceRoot}指向仓库根目录{projectName}会被替换为项目名这些占位符在配置解析时会被统一插值详见下文源码解析。输出路径中的令牌Token插值Nx 支持在outputs中使用占位符令牌解析时按以下规则插值见 packages/nx/src/tasks-runner/utils.ts{projectRoot}项目在仓库中的相对路径如apps/web{projectName}项目名称如web{workspaceRoot}仓库根目录{options.*}该 target 的 options 配置值例如{options.outputPath}{project.*}项目元数据中的字段向后兼容的旧式写法。同时Nx 的校验逻辑见 packages/nx/src/native/cache/validate_outputs.rs会要求outputs路径必须以{projectRoot}、{workspaceRoot}或{options.*}之一开头否则视为非法配置并报错这保证了输出路径始终可以解析到工作区内的确定位置。此外outputs支持取反!排除语法例如只缓存.next中除缓存目录外的内容{ outputs: [{projectRoot}/.next, !{projectRoot}/.next/cache] }在 Nx 的原生实现中见 packages/nx/src/native/cache/expand_outputs.rs 的测试用例这种“主输出 取反排除”的写法会被正确地展开为具体文件列表——测试中正是以apps/web/.next配合!apps/web/.next/cache验证排除逻辑的。底层原理getOutputsForTargetAndConfiguration的解析流程在 packages/nx/src/tasks-runner/utils.ts 中getOutputsForTargetAndConfiguration负责计算出某个任务实际会被缓存的全部输出路径其优先级为显式outputs若 target 配置了outputs则逐条插值令牌并做合法性校验返回插值后的路径集合outputPath选项若未声明outputs但配置中存在outputPath如{options.outputPath}形式则直接以该值作为输出路径默认值若以上都不存在则回退到内置默认——build/prepare任务返回dist/{projectRoot}、{projectRoot}/dist、{projectRoot}/build、{projectRoot}/public其他任务返回空数组。理解这条优先级链有助于排查“为什么我配置了.next却仍然缓存不到”的问题例如在project.json的buildtarget 中同时存在outputPath选项时Nx 会优先采用outputPath而非你手动声明的outputs实际上显式outputs的优先级最高会覆盖outputPath。验证缓存是否生效配置完成后可以通过以下方式验证.next是否被正确缓存与恢复首次运行构建执行pnpm nx build tasker/web对应本课程第 2 课用 Nx 运行任务的语法观察输出中任务是否以NX Successfully ran target build结束二次运行命中缓存不修改任何文件再次运行同一命令若命中缓存Nx 会输出Nx read the output from the cache并提示来自本地缓存此时.next目录已被恢复清理并恢复删除项目下的.next目录后再运行若仍能从缓存恢复说明outputs配置生效查看任务的完整配置可使用nx show project project-name --web或在编辑器中通过 Nx Console查看插件推断或手动声明的 inputs/outputs 详情确认.next出现在输出列表中。另外需要注意可缓存的任务必须是无副作用的——给定相同输入应当产生相同输出。例如依赖外部后端 API 状态的 e2e 测试不应启用缓存否则可能恢复过期结果。其他缓存调优参考若插件如nx/next已自动为build任务推断并配置缓存通常无需手动设置outputs插件会保证配置与底层工具如next.config保持同步若只需排除特定文件使缓存失效如修改*.md不触发重建可通过inputs配合取反语法实现例如[{projectRoot}/**/*, !{projectRoot}/**/*.md]详见缓存任务结果文档本地缓存生效后可进一步配置远程缓存在 CI 中跨机器共享缓存将单机命中的收益放大到整个流水线。【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表