第03章:AI帮我配置了package.json但没有锁定依赖版本
第03章:AI帮我配置了package.json但没有锁定依赖版本
“昨天还能正常运行的 CI,今天失败了——有人发布了一个新的 minor version,引入了一个 breaking change。或者本地开发没问题,部署到服务器上出现了莫名其妙的错误,因为本地 npm install 用的版本和服务器不一样。AI 给你的 package.json 里满是 ^ 前缀,这意味着每次 npm install 都可能装上不同版本。”
ℹ️ 版本说明:本章基于 Node.js v24.16.0 + npm 10.x。
3.1 AI默认会生成什么
// AI 通常给你的 package.json(全部用 ^ 前缀)
{
"dependencies": {
"express": "^5.0.0",
"prisma": "^5.22.0",
"zod": "^3.22.0",
"pino": "^9.0.0"
},
"devDependencies": {
"typescript": "^5.6.0",
"eslint": "^9.0.0"
}
}
^5.0.0 意味着允许安装 >=5.0.0 <6.0.0 的任意版本——每次 npm install 都可能装上不同版本。
3.2 AI通常遗漏的4个坑
⚠️ 坑1:package-lock.json 没有提交到 Git
# 很多人的 .gitignore 里误加了这一行
package-lock.json # ← 不应该忽略!
# package-lock.json 的作用:
# 锁定所有依赖(包括间接依赖)的精确版本
# 确保所有人 npm ci 都安装完全相同的版本
npm install vs npm ci:
npm install:读 package.json,安装满足版本范围的最新版,更新 lock 文件npm ci:读 package-lock.json,安装精确版本,lock 文件不存在则报错(CI 环境用这个)
CI 应该用 npm ci,不是 npm install。
⚠️ 坑2:依赖版本范围语义混淆
版本号格式:主版本.次版本.补丁版本(major.minor.patch)
主版本 = 不兼容变更(breaking changes)
次版本 = 向后兼容的新功能
补丁版本 = bug 修复
前缀含义:
^5.0.0 → >=5.0.0 <6.0.0(允许 minor + patch 升级)
~5.0.0 → >=5.0.0 <5.1.0(只允许 patch 升级,更保守)
5.0.0 → 精确版本(不自动升级)
* → 任意版本(危险!)
问题:即使是 minor 升级(^ 允许),也可能引入 breaking changes(发布者没有遵守语义化版本规范的情况并不少见)。
⚠️ 坑3:依赖安全漏洞没有自动检查
# 检查已知安全漏洞
npm audit
# 输出示例:
# 5 vulnerabilities (1 moderate, 3 high, 1 critical)
# Run `npm audit fix` to fix them
# 自动修复(升级到安全版本)
npm audit fix
# 如果有 breaking change 需要手动处理
npm audit fix --force # 谨慎!可能升级到 major version
# 在 CI 里加入安全检查(有漏洞时 CI 失败)
npm audit --audit-level=high # 只有 high/critical 时失败
⚠️ 坑4:peerDependencies 冲突导致不明错误
npm install
# npm WARN ERESOLVE overriding peer dependency
# npm WARN While resolving: my-ui-library@1.0.0
# npm WARN Found: react@18.0.0
# npm WARN node_modules/react
# npm WARN react@"^18.0.0" from the root project
# 这个警告意味着 my-ui-library 要求某个 react 版本,
# 但你安装的版本不完全兼容
# 可能导致运行时的隐蔽错误
解决方案:用 npm ls <package> 查看依赖树,理解版本冲突原因,再决定是否升级或降级。
3.3 更好的提示词
提示词 P01:生产级 package.json 配置
使用时机:为新项目或现有项目配置合理的依赖管理
帮我为一个 Node.js v24.16.0 项目配置生产级 package.json。
项目情况:
- 类型:[REST API / GraphQL API / 命令行工具]
- 框架:[Express 5.x / Fastify 5.x]
- 数据库:[PostgreSQL with Prisma / MongoDB with Mongoose]
- 部署方式:[Docker / PM2 / Kubernetes]
配置需求:
1. 版本锁定策略:
- dependencies:用 ^ 还是精确版本?什么情况下应该精确锁定?
- 对安全敏感包(如 crypto 相关):建议用精确版本?
2. scripts 配置(生产必备):
- "start": 生产环境启动命令
- "dev": 开发环境启动(nodemon/tsx)
- "build": 如果用 TypeScript,tsc 编译
- "test": vitest 或 jest
- "lint": eslint
- "audit": npm audit --audit-level=high
3. engines 字段(声明 Node.js 版本要求):
"engines": { "node": ">=24.0.0", "npm": ">=10.0.0" }
4. .npmrc 配置(CI 行为控制):
save-exact=true # npm install 时用精确版本(不加 ^)
engine-strict=true # Node.js 版本不满足时报错
5. 什么应该放在 devDependencies vs dependencies?
- TypeScript:devDependencies(编译时用,运行时不需要)
- eslint:devDependencies
- 类型定义包(@types/*):devDependencies
给我完整的 package.json 和 .npmrc 示例。
基于 Node.js v24.16.0 + npm 10.x。
提示词 P02:依赖更新策略
使用时机:现有项目的依赖管理和更新计划
帮我为现有 Node.js 项目制定依赖更新策略。
当前问题:
- 很多依赖落后了好几个大版本
- npm audit 显示有高危漏洞
- 不敢随便升级,怕破坏现有功能
更新策略:
1. 先查清楚现状:
npm outdated # 查看哪些包有新版本
npm audit # 查看安全漏洞
npx npm-check-updates # 显示所有可升级版本
2. 优先级排序(建议顺序):
P0:npm audit 里的 HIGH/CRITICAL 漏洞(立刻修复)
P1:直接依赖的 patch 升级(风险最低)
P2:直接依赖的 minor 升级
P3:major 版本升级(需要仔细阅读迁移指南)
3. 安全升级流程:
- 每次只升级一个包
- 升级后运行 npm test(需要有测试)
- 检查 CHANGELOG / Release Notes
4. 自动化工具:
- Dependabot(GitHub):自动创建依赖升级 PR
- Renovate:更灵活的依赖升级配置
- 如何配置 Dependabot 只自动合并 patch 升级?
5. 如何处理升级到 major 版本?
- 如何找到迁移指南?
- 如何用 git bisect 定位是哪次升级引入的问题?
基于 Node.js v24.16.0 + npm 10.x。
提示词 P03:monorepo 依赖管理
使用时机:多个 Node.js 包在同一个仓库里管理
帮我为 Node.js monorepo 配置依赖管理。
工具选择:
- npm workspaces(内置,v7+)
- pnpm workspaces(更快,磁盘空间更省)
- Turborepo(构建缓存)
我的 monorepo 结构:
packages/
api-server/ ← Node.js Express API
shared-utils/ ← 共享工具库
frontend/ ← React 前端
需求:
1. packages/shared-utils 如何被 api-server 引用?(本地包引用)
2. 所有包共用的 devDependencies(eslint、typescript)怎么放?
3. 某个包独有的依赖怎么管理?
4. 如何确保所有包使用相同版本的 react / express(防止版本冲突)?
5. CI 里如何只构建有改动的包(使用 Turborepo 缓存)?
给我:
- 根目录 package.json(workspaces 配置)
- 子包 package.json 示例
- .npmrc 配置
- GitHub Actions 里的 monorepo 构建配置
基于 Node.js v24.16.0 + npm workspaces。
3.4 验收清单
| 检查项 | 验证方法 | AI辅助 |
|---|---|---|
| package-lock.json 在 Git 里 | git ls-files package-lock.json |
从 .gitignore 移除 |
| CI 用 npm ci(不是 npm install) | CI 脚本里有 npm ci |
用 P01 更新 CI |
| npm audit 无 HIGH/CRITICAL | npm audit --audit-level=high 退出码为0 |
用 P02 修复漏洞 |
| engines 字段指定 Node.js 版本 | package.json 有 engines 字段 | 用 P01 添加 |
| 有 Dependabot 或 Renovate 配置 | .github/dependabot.yml 存在 | 用 P02 配置 |
| .npmrc 有 save-exact | 新 install 的包用精确版本 | 用 P01 配置 |
3.5 本章小结
如果你只记一件事:把 package-lock.json 提交到 Git,CI 里用 npm ci 而不是 npm install。npm ci 使用 lock 文件安装精确版本,确保每次构建的依赖完全一致——这是"我本地没问题但服务器出错"问题的最常见根因之一。
依赖管理的三个层次:
- 版本锁定(lock 文件 + npm ci):确保开发、CI、生产安装完全相同的依赖树
- 安全扫描(npm audit + Dependabot):定期检查已知漏洞,HIGH/CRITICAL 立刻修复
- 依赖更新策略(patch/minor/major 分级处理):patch 自动合并,minor 测试后合并,major 手动迁移
→ 第4章:AI生成的Node.js应用内存泄漏排查