用输入键复用工作
构建缓存类似记忆化函数。每一步声明输入:源文件、依赖锁文件、编译参数和环境变量。缓存把这些输入哈希成键,并把输出存在该键下。下次构建命中相同键时直接恢复输出,而不是重新计算。容器构建按层应用同一思路,monorepo 工具按包应用。
- uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
何时使用
当构建重复执行相同步骤时使用缓存:每次推送都跑 CI、monorepo 构建大量包、或者容器镜像每次只改一层。依赖安装时间和测试规模越大,收益越明显。如果项目几秒就能构建完成,缓存配置的成本可能高于收益。
权衡
代价是正确性。忽略编译器版本或环境变量的缓存键会返回与源码不匹配的产物。远程缓存需要访问控制,因为被污染的产物可能在后续构建中执行。存储与网络传输也有成本,而低命中率会同时承担两边的损失。
示例与常见误解
某 monorepo 有四十个包,每个包的构建都以源码和锁文件为键缓存。修改一个包只会重建它及其下游依赖,其余三十八个包不受影响。常见误解是缓存总是划算:测量命中率和恢复耗时本身就是设计的一部分。相关概念包括 CI/CD、monorepo 与依赖固定。