依赖版本锁定、私有包、禁止引入包清单
- Requirement:生产依赖(
dependencies)使用 ~(锁定 PATCH)或精确版本号,禁止使用 ^(允许 MINOR 升级)或 *(任意版本)。
- Requirement:开发依赖(
devDependencies)可使用 ^,但必须有 lockfile 锁定实际版本。
- Standard:新项目推荐使用精确版本号(无范围符),确保可复现构建。
| 范围符 | 含义 | 允许版本 | 场景 |
|---|
1.2.3 | 精确版本 | 仅 1.2.3 | 生产依赖(推荐) |
~1.2.3 | 锁定 PATCH | ≥1.2.3 <1.3.0 | 生产依赖 |
^1.2.3 | 锁定 MAJOR | ≥1.2.3 <2.0.0 | 开发依赖 |
>=1.2.3 | 大于等于 | 无上限 | 禁止 |
* / latest | 任意版本 | 任意 | 禁止 |
- Requirement:lockfile(
package-lock.json、yarn.lock、pnpm-lock.yaml、poetry.lock、go.sum)必须提交到版本库。
- Requirement:CI 环境使用
npm ci(或 pnpm install --frozen-lockfile、yarn install --frozen-lockfile)安装依赖,确保与 lockfile 一致。
- Caution:禁止手动修改 lockfile,必须通过包管理器命令更新。
{
"dependencies": {
"react": "18.2.0",
"axios": "~1.6.0",
"lodash": "4.17.21"
},
"devDependencies": {
"typescript": "^5.3.0",
"eslint": "^8.56.0",
"vite": "^5.0.0"
}
}
- Requirement:使用
pyproject.toml + poetry.lock 或 requirements.txt + requirements-dev.txt 管理依赖。
- Standard:
requirements.txt 中使用 == 锁定精确版本。
- Requirement:使用 Go Modules(
go.mod + go.sum),go.mod 中版本由 go get 管理。
- Standard:使用
go mod tidy 清理未使用依赖,定期执行。
- Requirement:私有包必须从公司私有 Registry 拉取,禁止直接从公共 Registry 拉取内部包。
- Standard:在项目根目录配置
.npmrc 指定私有 Registry 与作用域。
# .npmrc
@company:registry=https://npm.company.com/
//npm.company.com/:_authToken=${NPM_TOKEN}
always-auth=true
- Standard:Python 私有源配置在
pyproject.toml 或 pip.conf 中。
# pyproject.toml (poetry)
[[tool.poetry.source]]
name = "company"
url = "https://pypi.company.com/simple/"
priority = "supplemental"
- Requirement:私有 npm 包必须使用公司 scope,如
@company/user-service。
- Standard:私有包版本号遵循 版本号规范。
- Standard:私有包必须包含 README、CHANGELOG、LICENSE。
- Requirement:私有 Registry 的访问 token 必须通过环境变量注入,禁止硬编码到
.npmrc 或代码中。
- Standard:CI 环境通过 Secret 管理注入 token,本地开发通过
.npmrc 本地配置(不提交到仓库)。
- Requirement:禁止引入存在已知高危漏洞且无修复版本的依赖。
- Requirement:禁止引入长期未维护(最近一次发布 > 2 年)的依赖,除非有明确的替代评估记录。
- Requirement:禁止引入许可证不兼容(如 GPL 传染协议)的闭源项目依赖。
- Caution:禁止引入功能重复的依赖,如同时使用
lodash 与 underscore、moment 与 dayjs。
| 包名 | 禁止原因 | 替代方案 |
|---|
moment.js | 体积大、已停止维护 | dayjs、date-fns、luxon |
request | 已废弃 | axios、fetch、got |
jquery | 现代框架无需直接操作 DOM | 框架 API、原生 DOM |
lodash(全量引入) | 体积大 | lodash-es 按需引入、原生 ES 方法 |
babel-polyfill | 已废弃 | core-js + regenerator-runtime |
node-sass | 已废弃、安装问题多 | sass(Dart Sass) |
| 包名 | 禁止原因 | 替代方案 |
|---|
log4j < 2.17.1 | 存在 RCE 漏洞 | 升级到最新版 |
fastjson < 1.2.83 | 反序列化漏洞 | jackson、升级 fastjson |
commons-collections < 3.2.2 | 反序列化漏洞 | 升级或移除 |
- Standard:引入新的生产依赖必须经过 Code Review,并在 PR 中说明:
- 引入原因与解决的问题。
- 是否有更轻量的替代方案。
- 包的维护状态(最近更新时间、Star 数、Issue 响应)。
- 许可证类型。
- Suggestion:可使用 Bundlephobia 评估前端依赖体积。
- Standard:生产依赖升级遵循”小版本及时、大版本评估”原则:
- PATCH 升级:可直接合并(需通过 CI)。
- MINOR 升级:需验证功能兼容性。
- MAJOR 升级:需编写迁移方案,经评审后执行。
- Caution:禁止一次性升级多个不相关依赖,应逐个升级并验证。
- 使用
npm outdated / pnpm outdated / pip list --outdated 检查可升级依赖。
- 阅读目标版本的 CHANGELOG,确认无破坏性变更。
- 创建独立分支
chore/deps-upgrade-xxx。
- 升级依赖并运行完整测试套件。
- 提交 PR,注明升级内容与风险点。
- Code Review 通过后合入。
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
labels:
- "dependencies"
- Requirement:CI 流水线必须集成依赖安全扫描,发现高危漏洞时阻断合并。
- Standard:常用工具:
- 前端:
npm audit、pnpm audit、Snyk、OSV-Scanner。
- Python:
pip-audit、Safety、Snyk。
- Java:OWASP Dependency-Check、Snyk。
- Go:
govulncheck。
- Requirement:高危(Critical / High)漏洞必须在 7 天内修复,无法修复时需有临时缓解措施并记录。
- Standard:中危(Medium)漏洞在 30 天内修复。
- Standard:低危(Low)漏洞在下个迭代版本中修复。
- Caution:漏洞修复优先升级到官方修复版本,禁止使用未经验证的 fork 版本。
# .gitlab-ci.yml
dependency_scan:
stage: test
script:
- npm ci
- npm audit --audit-level=high
allow_failure: false # 高危漏洞阻断
- Standard:对于无法立即修复且有缓解措施的漏洞,可申请豁免,需在仓库中记录豁免原因与过期时间。
# .snyk
version: v1.13.5
ignore:
SNYK-JS-LODASH-1018905:
- '*':
reason: "No exploit path available; lodash used only for debounce."
expires: 2024-12-31
| 反模式 | 问题 | 建议 |
|---|
dependencies 使用 ^ 或 * | 构建不可复现,可能引入不兼容版本 | 使用精确版本或 ~ |
| 不提交 lockfile | 团队成员安装版本不一致 | 必须提交 lockfile |
| 手动修改 lockfile | 导致依赖树损坏 | 通过包管理器命令更新 |
CI 使用 npm install | 可能自动升级依赖 | 使用 npm ci |
| 同时引入功能重复的依赖 | 包体积膨胀、维护成本高 | 只保留一个 |
| 引入未维护的依赖 | 安全风险、无人修复 bug | 评估替代方案 |
| 一次性升级所有依赖 | 难以定位问题 | 逐个升级并验证 |
| 跳过安全扫描 | 漏洞进入生产 | CI 强制扫描 |