# npm 依赖安装与缓存 Action 这个 GitHub Action 自动处理 npm 依赖的缓存和安装,支持多种包管理器(npm、pnpm、yarn),可以大幅提升 CI/CD 流水线的执行速度。 ## ✨ 特性 - 🚀 **智能缓存**: 自动缓存 node_modules,避免重复安装 - 📦 **多包管理器支持**: 支持 npm、pnpm、yarn,自动检测标准锁文件 - 🎯 **灵活配置**: 可自定义缓存前缀、安装命令等 - 🔑 **精确 hash 控制**: 支持自定义缓存 hash,确保依赖变化时缓存失效 - 🔄 **Git 集成**: 可选的 git stash 功能 - 📊 **详细输出**: 提供缓存命中状态和使用的缓存 key ## 📋 输入参数 | 参数名 | 描述 | 是否必需 | 默认值 | | ------------------- | ---------------------------- | -------- | -------------- | | `package-manager` | 包管理器类型 (npm/pnpm/yarn) | 否 | `npm` | | `cache-prefix` | 缓存前缀名称 | 否 | `modules` | | `node-modules-path` | node_modules 目录路径 | 否 | `node_modules` | | `force-install` | 是否强制安装 | 否 | `false` | | `enable-git-stash` | 安装后是否执行 git stash | 否 | `false` | | `install-command` | 自定义安装命令(覆盖默认) | 否 | `''` | | `cache-hash` | 缓存 hash 值(**推荐使用**) | 否 | 自动计算 | ## 📤 输出参数 | 参数名 | 描述 | | ----------- | ------------------------- | | `cache-hit` | 是否命中缓存 (true/false) | | `cache-key` | 使用的缓存 key | ## 💡 重要提示 **强烈推荐使用 `cache-hash` 参数!** 使用 `cache-hash` 参数有以下优势: - ✅ **精确控制**: 让你完全控制缓存失效的条件 - ✅ **环境兼容**: 避免在不同容器环境中 hash 计算不一致的问题 - ✅ **灵活组合**: 可以组合多个文件的 hash(如 `package.json` + `package-lock.json` + `.nvmrc`) - ✅ **调试友好**: 在 workflow 中可以清楚看到使用的 hash 值 ```yaml # 推荐用法 with: cache-hash: ${{ hashFiles('package-lock.json') }} ``` 如果不提供 `cache-hash`,action 会自动使用 `package.json` 作为 fallback,但不如手动指定精确。 ## 🚀 使用方法 ### 基础用法 (npm) ```yaml - name: 安装npm依赖 uses: actions/xgj/npm-install@v1 ``` ### 使用 pnpm ```yaml - name: 安装pnpm依赖 uses: actions/xgj/npm-install@v1 with: package-manager: "pnpm" ``` ### 强制安装 + Git Stash ```yaml - name: 强制安装依赖并stash uses: actions/xgj/npm-install@v1 with: package-manager: "npm" force-install: "true" enable-git-stash: "true" ``` ### 自定义缓存配置 ```yaml - name: 自定义缓存安装 uses: actions/xgj/npm-install@v1 with: package-manager: "yarn" cache-prefix: "my-project" node-modules-path: "./frontend/node_modules" ``` ### 自定义安装命令 ```yaml - name: 使用自定义命令安装 uses: actions/xgj/npm-install@v1 with: install-command: "npm ci --only=production" ``` ### 使用自定义缓存 hash(推荐用法) ```yaml # 推荐:手动指定缓存hash,确保精确的缓存管理 - name: 安装npm依赖 uses: actions/xgj/npm-install@v1 with: package-manager: "npm" cache-hash: ${{ hashFiles('package-lock.json') }} # pnpm项目 - name: 安装pnpm依赖 uses: actions/xgj/npm-install@v1 with: package-manager: "pnpm" cache-hash: ${{ hashFiles('pnpm-lock.yaml') }} # 多文件hash组合 - name: 安装依赖(多文件hash) uses: actions/xgj/npm-install@v1 with: package-manager: "npm" cache-hash: ${{ hashFiles('package.json', 'package-lock.json', '.nvmrc') }} ``` ### 检查缓存状态 ```yaml - name: 安装依赖 id: install-deps uses: actions/xgj/npm-install@v1 with: package-manager: "pnpm" - name: 根据缓存状态执行操作 if: steps.install-deps.outputs.cache-hit != 'true' run: | echo "依赖已重新安装,执行额外步骤" npm run build:fresh ``` ## 📝 完整工作流示例 ```yaml name: CI Pipeline on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - name: 检出代码 uses: actions/checkout@v4 - name: 设置Node.js uses: actions/setup-node@v4 with: node-version: "18" - name: 安装依赖 id: deps uses: actions/xgj/npm-install@v1 with: package-manager: "pnpm" force-install: "false" - name: 运行测试 run: pnpm test - name: 构建项目 if: steps.deps.outputs.cache-hit != 'true' run: pnpm build ``` ## 🔧 工作原理 1. **缓存 Key 生成**: 根据包管理器类型和 lock 文件生成唯一的缓存 key 2. **缓存检查**: 使用`actions/cache@v4`检查是否存在匹配的缓存 3. **条件安装**: 仅在缓存未命中时执行依赖安装 4. **可选操作**: 根据配置执行 git stash 等额外操作 ## 🎯 最佳实践 ### 1. 选择合适的包管理器 ```yaml # 推荐:根据项目实际使用的包管理器 - uses: actions/xgj/npm-install@v1 with: package-manager: "pnpm" # 如果项目使用pnpm ``` ### 2. 合理使用强制安装 ```yaml # 仅在必要时使用强制安装 - uses: actions/xgj/npm-install@v1 with: force-install: "true" # 仅用于解决依赖冲突 ``` ### 3. 自定义缓存前缀避免冲突 ```yaml # 为不同项目使用不同的缓存前缀 - uses: actions/xgj/npm-install@v1 with: cache-prefix: "frontend-app" ``` ### 4. 利用输出参数优化流程 ```yaml - name: 安装依赖 id: install uses: actions/xgj/npm-install@v1 # 仅在重新安装依赖时执行某些步骤 - name: 重建缓存 if: steps.install.outputs.cache-hit != 'true' run: npm run build:cache ``` ## 🚨 注意事项 1. **Git Stash**: 启用`enable-git-stash`会在安装后执行`git stash`,请确保这符合你的工作流需求 2. **缓存大小**: node_modules 可能很大,请关注 GitHub Actions 的缓存限制 3. **Lock 文件**: 确保 lock 文件已提交到仓库,这是缓存 key 生成的基础 4. **权限**: 某些自定义安装命令可能需要额外的权限 ## 🔍 故障排除 ### 缓存未命中 如果缓存总是未命中,检查: - lock 文件是否存在且已提交 - package.json 或 lock 文件是否有变更 - 缓存前缀是否与之前一致 ### 安装失败 如果安装失败,尝试: - 启用`force-install` - 使用自定义安装命令 - 检查 Node.js 版本兼容性 ### Git Stash 问题 如果 git stash 出现问题: - 确保工作目录有可 stash 的变更 - 考虑禁用`enable-git-stash` - 在 action 之前确保 git 配置正确