dependency-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDependency Management
依赖项管理
Third-party dependencies are simultaneously the most powerful and most dangerous part of modern software. A single mismanaged dependency caused log4shell. Left-pad took down thousands of builds in 11 minutes. Supply chain attacks through dependency confusion hit major enterprises. This skill covers the full lifecycle: choosing, pinning, auditing, updating, and removing dependencies with production discipline.
第三方依赖项是现代软件中最强大同时也是最危险的组成部分。一个管理不当的依赖项就引发了Log4Shell漏洞事件。Left-pad包曾在11分钟内导致数千个构建任务失败。通过依赖混淆发起的供应链攻击也曾重创多家大型企业。本技能涵盖依赖项管理的完整生命周期:以生产级严谨性进行依赖项的选择、版本固定、审计、更新和移除。
When to Use
适用场景
Use for:
- Deciding whether to add a new dependency
- Version pinning strategy (exact vs range vs lockfile-only)
- Setting up automated update workflows (Renovate, Dependabot)
- Security auditing with ,
npm audit, Snyk, Socket.devpip audit - License compliance scanning (MIT/Apache/GPL compatibility)
- Generating Software Bills of Materials (SBOM)
- Resolving peer dependency conflicts and npm overrides
- Responding to security advisories and CVEs
- Detecting typosquatting and dependency confusion attacks
NOT for:
- Internal monorepo package management (use )
monorepo-management - Publishing your own packages to npm, PyPI, crates.io
- Package manager configuration beyond dependency management (workspace config, etc.)
- Vendoring and air-gapped environments (mention these exist but they're outside scope)
适用情况:
- 判断是否添加新依赖项
- 版本固定策略(精确版本 vs 版本范围 vs 仅锁文件)
- 设置自动化更新工作流(Renovate、Dependabot)
- 使用、
npm audit、Snyk、Socket.dev进行安全审计pip audit - 许可证合规性扫描(MIT/Apache/GPL兼容性)
- 生成软件物料清单(SBOM)
- 解决peer dependency冲突和npm overrides
- 响应安全公告和CVE漏洞
- 检测typosquatting和依赖混淆攻击
不适用情况:
- 内部单体仓库包管理(请使用)
monorepo-management - 向npm、PyPI、crates.io发布自有包
- 依赖项管理之外的包管理器配置(如工作区配置等)
- 依赖包本地化和离线环境(仅提及此类场景存在,但不在本技能范围内)
Core Decision: Should I Add This Dependency?
核心决策:是否添加该依赖项?
mermaid
flowchart TD
Start[Want to add a dependency?] --> Size{How much code does it replace?}
Size -->|< 20 lines| Write[Write it yourself]
Size -->|20-200 lines| Q2{Trivial to implement correctly?}
Size -->|> 200 lines| Q3{Check the package}
Q2 -->|Yes, pure logic| Write
Q2 -->|No, edge cases / locale / timezone| Q3
Q3 --> Audit{Run audit checks}
Audit --> Downloads{Weekly downloads?}
Downloads -->|< 10k| HighRisk[High risk: low adoption]
Downloads -->|10k-100k| MedRisk[Medium: check actively]
Downloads -->|> 100k| Maintained{Actively maintained?}
Maintained -->|Last commit > 2 years| Fork[Consider fork or alternative]
Maintained -->|Recent commits| License{License compatible?}
License -->|GPL in proprietary| Reject[REJECT: license issue]
License -->|MIT / Apache 2.0| Security{npm audit / Socket.dev scan?}
Security -->|CVEs unfixed| Reject
Security -->|Clean| Transitive{Transitive dep count?}
Transitive -->|> 50 new deps| Reconsider[Reconsider: high blast radius]
Transitive -->|< 50 new deps| Accept[Add with pinned version]
HighRisk --> Fork
MedRisk --> Maintainedmermaid
flowchart TD
Start[Want to add a dependency?] --> Size{How much code does it replace?}
Size -->|< 20 lines| Write[Write it yourself]
Size -->|20-200 lines| Q2{Trivial to implement correctly?}
Size -->|> 200 lines| Q3{Check the package}
Q2 -->|Yes, pure logic| Write
Q2 -->|No, edge cases / locale / timezone| Q3
Q3 --> Audit{Run audit checks}
Audit --> Downloads{Weekly downloads?}
Downloads -->|< 10k| HighRisk[High risk: low adoption]
Downloads -->|10k-100k| MedRisk[Medium: check actively]
Downloads -->|> 100k| Maintained{Actively maintained?}
Maintained -->|Last commit > 2 years| Fork[Consider fork or alternative]
Maintained -->|Recent commits| License{License compatible?}
License -->|GPL in proprietary| Reject[REJECT: license issue]
License -->|MIT / Apache 2.0| Security{npm audit / Socket.dev scan?}
Security -->|CVEs unfixed| Reject
Security -->|Clean| Transitive{Transitive dep count?}
Transitive -->|> 50 new deps| Reconsider[Reconsider: high blast radius]
Transitive -->|< 50 new deps| Accept[Add with pinned version]
HighRisk --> Fork
MedRisk --> MaintainedVersion Pinning Strategy
版本固定策略
Semver Semantics Recap
Semver语义回顾
^1.2.3 = >= 1.2.3, < 2.0.0 (minor + patch updates allowed)
~1.2.3 = >= 1.2.3, < 1.3.0 (patch updates only)
1.2.3 = exactly 1.2.3 (locked)
* = any version (never use)^1.2.3 = >= 1.2.3, < 2.0.0 (允许minor和patch更新)
~1.2.3 = >= 1.2.3, < 1.3.0 (仅允许patch更新)
1.2.3 = exactly 1.2.3 (完全锁定)
* = any version (绝对不要使用)When to Use Each
各策略适用场景
| Strategy | Where | Reasoning |
|---|---|---|
Exact pinning ( | Production apps | Reproducible builds; lockfile provides flexibility |
Tilde ( | Libraries you publish | Patch safety; minor versions may break consumers |
Caret ( | Dev tooling only | Acceptable churn for formatters, linters |
| Lockfile as truth | All production | |
Never | Anywhere | Catastrophic: installs whatever is latest at build time |
| 策略 | 适用场景 | 理由 |
|---|---|---|
精确固定版本 ( | 生产应用 | 可重现构建;锁文件提供灵活性 |
Tilde ( | 发布的类库 | 补丁更新安全;minor版本可能破坏消费者代码 |
Caret ( | 仅开发工具 | 格式化工具、代码检查工具可接受频繁更新 |
| 锁文件作为唯一依据 | 所有生产环境 | 使用 |
绝对不要使用 | 任何场景 | 风险极高:构建时会安装最新版本,可能导致灾难性问题 |
Anti-Pattern: Caret in Production App Dependencies
反模式:生产应用依赖项使用Caret范围
Novice: "I use so I always get bug fixes automatically. That's safer."
Expert: Caret ranges mean any breaking-within-semver change installs without your knowledge. Semver is aspirational, not enforced — packages regularly ship breaking changes in minor versions. Your lockfile prevents this on developer machines, but CI environments that run instead of will silently upgrade. Pin your direct dependencies exactly and let the lockfile manage transitive deps. Review updates deliberately via Renovate or Dependabot PRs.
Detection: Check for prefixes on runtime dependencies in production apps. Run on a fresh clone and compare the installed tree to your last deployment.
^npm installnpm cipackage.json^npm ci新手:"我使用,这样就能自动获取bug修复,更安全。"
专家:Caret范围意味着任何符合Semver但实际包含破坏性变更的版本都会在你不知情的情况下被安装。Semver是一种约定而非强制标准——很多包经常在minor版本中发布破坏性变更。你的锁文件可以在开发机器上避免这种情况,但运行而非的CI环境会静默升级。请精确固定直接依赖项的版本,让锁文件管理传递依赖项。通过Renovate或Dependabot的PR来审慎审查更新。
检测方法:检查生产应用中运行时依赖项是否带有前缀。在全新克隆的代码上运行,并将安装的依赖树与上次部署的版本进行对比。
^npm installnpm cipackage.json^npm ciUpdate Workflow Decision
更新工作流决策
mermaid
flowchart TD
Update[How to handle updates?] --> Auto{Use automation?}
Auto -->|Yes| Tool{Which tool?}
Auto -->|No, manual| Manual[Monthly audit: npm outdated / pip list --outdated]
Tool -->|GitHub repo| Dependabot[GitHub Dependabot]
Tool -->|Any platform| Renovate[Renovate Bot — more powerful]
Dependabot --> DConfig[Configure .github/dependabot.yml]
Renovate --> RConfig[Configure renovate.json]
DConfig --> DGroup{Group updates?}
RConfig --> RGroup{Group updates?}
DGroup -->|Yes| DGrouped[Group patch updates together]
DGroup -->|No| DPR[One PR per dependency]
RGroup -->|Yes| RGrouped[Group by type: devDeps patch / prod minor]
RGroup -->|No| RPR[One PR per dependency]
RGrouped --> AutoMerge{Automerge safe?}
DGrouped --> AutoMerge
AutoMerge -->|Dev deps + patch only| EnableAM[Enable automerge with test gate]
AutoMerge -->|Prod deps, major versions| RequireReview[Require human review]mermaid
flowchart TD
Update[How to handle updates?] --> Auto{Use automation?}
Auto -->|Yes| Tool{Which tool?}
Auto -->|No, manual| Manual[Monthly audit: npm outdated / pip list --outdated]
Tool -->|GitHub repo| Dependabot[GitHub Dependabot]
Tool -->|Any platform| Renovate[Renovate Bot — more powerful]
Dependabot --> DConfig[Configure .github/dependabot.yml]
Renovate --> RConfig[Configure renovate.json]
DConfig --> DGroup{Group updates?}
RConfig --> RGroup{Group updates?}
DGroup -->|Yes| DGrouped[Group patch updates together]
DGroup -->|No| DPR[One PR per dependency]
RGroup -->|Yes| RGrouped[Group by type: devDeps patch / prod minor]
RGroup -->|No| RPR[One PR per dependency]
RGrouped --> AutoMerge{Automerge safe?}
DGrouped --> AutoMerge
AutoMerge -->|Dev deps + patch only| EnableAM[Enable automerge with test gate]
AutoMerge -->|Prod deps, major versions| RequireReview[Require human review]Security Auditing
安全审计
The Audit Stack
审计工具栈
Run these in sequence from fastest/free to deepest:
bash
undefined按从快/免费到深度分析的顺序运行以下工具:
bash
undefined1. npm audit (built-in, free, fast — checks known CVEs)
1. npm audit(内置工具,免费,快速——检查已知CVE)
npm audit
npm audit --audit-level=high # Only high+ severity
npm audit fix # Auto-fix where possible
npm audit fix --force # ⚠️ May break API — review first
npm audit
npm audit --audit-level=high # 仅检查高及以上严重级别
npm audit fix # 自动修复可行的问题
npm audit fix --force # ⚠️ 可能破坏API——修复前需审查
2. pip audit (Python equivalent)
2. pip audit(Python对应工具)
pip install pip-audit
pip-audit
pip-audit --fix # Write fixed requirements.txt
pip install pip-audit
pip-audit
pip-audit --fix # 写入修复后的requirements.txt
3. Socket.dev (supply chain analysis beyond CVEs)
3. Socket.dev(超越CVE的供应链分析)
npx socket check # Checks for malicious behavior, typosquatting
npx socket check # 检查恶意行为、typosquatting
4. Snyk (deeper analysis, CI integration)
4. Snyk(深度分析,CI集成)
npx snyk test
npx snyk monitor # Continuous monitoring
npx snyk test
npx snyk monitor # 持续监控
5. SBOM generation (for compliance)
5. SBOM生成(合规性要求)
npx @cyclonedx/cyclonedx-npm --output-format json > sbom.json
npx @cyclonedx/cyclonedx-npm --output-format json > sbom.json
Python: pip install cyclonedx-bom && cyclonedx-py -p
Python: pip install cyclonedx-bom && cyclonedx-py -p
undefinedundefinedAnti-Pattern: Ignoring Security Advisories
反模式:忽略安全公告
Novice: "The audit shows vulnerabilities but they're in dev dependencies or unused code paths. Not a risk."
Expert: Dev dependencies reach production in two ways: (1) build tools that process production code can be compromised, and (2) the advisory may be rated "dev-only" but the package is actually in your production bundle. Check with to trace the dependency chain. For genuinely dev-only packages (mocha, jest, eslint), moderate severity advisories can be deferred. Critical/high severity — even in dev deps — should be resolved within your SLA. "Not a risk" is an assessment, not a skip; document it.
Detection: Run to scope to production-only deps. Check to see all consumers.
npm ls <package>npm audit --productionnpm ls <vulnerable-pkg>新手:"审计显示存在漏洞,但它们在开发依赖项或未使用的代码路径中,没有风险。"
专家:开发依赖项有两种途径进入生产环境:(1) 处理生产代码的构建工具可能被攻陷;(2) 公告标记为"仅开发环境"的包实际上可能被包含在生产打包文件中。使用追踪依赖链。对于真正的开发-only包(如mocha、jest、eslint),中等严重级别的公告可以延迟处理。但即使是开发依赖项中的严重/高危漏洞,也应在你的服务级别协议(SLA)内解决。"没有风险"是一种评估而非忽略,需记录评估过程。
检测方法:运行仅排查生产依赖项。使用查看所有依赖该包的模块。
npm ls <package>npm audit --productionnpm ls <vulnerable-pkg>Supply Chain Security
供应链安全
Typosquatting Detection
Typosquatting检测
Common attack patterns:
- →
lodash(digit 1 instead of letter l)1odash - →
express(missing character)expres - →
react(capitalization — case-sensitive registries)React - →
@org/package(scope confusion)org-package
bash
undefined常见攻击模式:
- →
lodash(数字1替代字母l)1odash - →
express(缺失字符)expres - →
react(大小写差异——区分大小写的仓库)React - →
@org/package(作用域混淆)org-package
bash
undefinedSocket.dev catches most of these
Socket.dev可检测大多数此类攻击
npx socket check
npx socket check
Manual: verify before install
手动检测:安装前验证
npm view <package-name> # Check metadata: author, description, repo URL
npm view <package-name> repository # Verify GitHub repo matches official source
undefinednpm view <package-name> # 检查元数据:作者、描述、仓库URL
npm view <package-name> repository # 验证GitHub仓库是否与官方源一致
undefinedDependency Confusion Attack
依赖混淆攻击
An attacker publishes a public package with the same name as your private . The package manager fetches the public one because it has a higher version number.
@org/packagePrevention:
bash
undefined攻击者发布一个与你的私有同名的公共包。由于公共包版本号更高,包管理器会拉取公共包。
@org/package预防措施:
bash
undefinednpm: Use .npmrc scoped registry config
npm:使用.npmrc配置作用域仓库
@your-org:registry=https://your-private-registry.example.com
@your-org:registry=https://your-private-registry.example.com
Or set resolutions/overrides to lock the source
或设置resolutions/overrides锁定源
package.json:
package.json:
{
"overrides": {
"@your-org/internal-package": "npm:@your-org/internal-package@^1.0.0"
}
}
undefined{
"overrides": {
"@your-org/internal-package": "npm:@your-org/internal-package@^1.0.0"
}
}
undefinedLockfile Integrity
锁文件完整性
bash
undefinedbash
undefinedNever commit node_modules — commit only the lockfile
永远不要提交node_modules——仅提交锁文件
Verify lockfile integrity after pulls
拉取代码后验证锁文件完整性
npm ci # Fails if lockfile doesn't match package.json
# NEVER use npm install in CI
npm ci # 如果锁文件与package.json不匹配则失败
# CI环境中绝对不要使用npm install
Python: use pip-compile for deterministic locks
Python:使用pip-compile生成确定性锁文件
pip install pip-tools
pip-compile requirements.in # Generates pinned requirements.txt
pip-sync requirements.txt # Install exactly this
---pip install pip-tools
pip-compile requirements.in # 生成固定版本的requirements.txt
pip-sync requirements.txt # 精确安装该文件中的依赖项
---License Compliance
许可证合规性
Compatibility Matrix
兼容性矩阵
| Your Project | MIT dep | Apache 2.0 dep | LGPL dep | GPL dep |
|---|---|---|---|---|
| Proprietary | OK | OK (attribution) | OK (dynamic link) | REJECT |
| MIT/Apache | OK | OK | OK | Complicated |
| GPL | OK | OK | OK | OK |
bash
undefined| 你的项目 | MIT依赖 | Apache 2.0依赖 | LGPL依赖 | GPL依赖 |
|---|---|---|---|---|
| 专有项目 | 允许 | 允许(需注明出处) | 允许(动态链接) | 拒绝 |
| MIT/Apache项目 | 允许 | 允许 | 允许 | 复杂(需谨慎) |
| GPL项目 | 允许 | 允许 | 允许 | 允许 |
bash
undefinedScan all licenses in your dependency tree
扫描依赖树中的所有许可证
npx license-checker --production --onlyAllow "MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD"
npx license-checker --production --failOn "GPL;AGPL"
npx license-checker --production --onlyAllow "MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD"
npx license-checker --production --failOn "GPL;AGPL"
Python
Python
pip install pip-licenses
pip-licenses --format=markdown --order=license
undefinedpip install pip-licenses
pip-licenses --format=markdown --order=license
undefinedAnti-Pattern: Excessive Dependencies for Trivial Functionality
反模式:为 trivial 功能引入过多依赖
Novice: (actual package, 54M weekly downloads). Installs a package with 1 line of code: .
Expert: The left-pad incident (2016) proved that trivial utility packages are operational liabilities. Every production dependency is: a potential CVE vector, a supply chain attack surface, a semver conflict source, and a cognitive load item. Before adding a package, paste the README into ChatGPT and ask "is the core functionality < 20 lines?" For date manipulation, string utilities, and math operations, write the function. For localization, cryptography, protocol parsing — use battle-tested libraries.
Detection: Run or check npm page for source code size. Packages under 10KB for non-trivial domains are almost always replaceable.
Timeline: Post-left-pad (2016) the ecosystem became more aware of this, but the pattern persists. In 2024 the CDN compromise showed this applies to CDN dependencies too.
npm install is-oddn % 2 !== 0npx cost-of-modulespolyfill.io新手:(真实存在的包,周下载量5400万)。该包仅包含一行代码:。
专家:2016年的Left-pad事件证明,微小的工具包是运营风险的来源。每个生产依赖项都是:潜在的CVE载体、供应链攻击面、Semver冲突源,以及认知负担项。添加包之前,将README粘贴到ChatGPT中,询问"核心功能是否少于20行?" 对于日期处理、字符串工具和数学运算,请自行编写函数。对于本地化、加密、协议解析——使用经过实战检验的类库。
检测方法:运行或查看npm页面的源代码大小。非复杂领域下小于10KB的包几乎都可以被替代。
时间线:Left-pad事件(2016)后,生态系统开始意识到这一问题,但该模式仍持续存在。2024年 CDN被攻陷事件表明,这一问题同样适用于CDN依赖项。
npm install is-oddn % 2 !== 0npx cost-of-modulespolyfill.ionpm Overrides and Resolutions
npm Overrides与Resolutions
Use to fix vulnerable transitive dependencies when the direct dependency hasn't updated:
json
// package.json — npm overrides (npm 8.3+)
{
"overrides": {
"semver": ">=7.5.2", // Force minimum version across all deps
"lodash": "4.17.21", // Force exact version
"vulnerable-pkg": {
"sub-dependency": "^2.0.0" // Scoped: only for this parent
}
}
}json
// package.json — yarn/pnpm resolutions
{
"resolutions": {
"semver": ">=7.5.2"
}
}Caution: Overrides can break packages that genuinely require the older API. Always run your test suite after adding overrides.
当直接依赖项未更新时,使用该功能修复存在漏洞的传递依赖项:
json
// package.json — npm overrides(npm 8.3+)
{
"overrides": {
"semver": ">=7.5.2", // 强制所有依赖项使用最低版本
"lodash": "4.17.21", // 强制使用精确版本
"vulnerable-pkg": {
"sub-dependency": "^2.0.0" // 作用域:仅针对该父依赖项
}
}
}json
// package.json — yarn/pnpm resolutions
{
"resolutions": {
"semver": ">=7.5.2"
}
}注意:Overrides可能会破坏真正需要旧版API的包。添加Overrides后务必运行测试套件。
Peer Dependencies
Peer Dependencies
bash
undefinedbash
undefinedCheck what peer deps a package needs
查看包所需的peer依赖项
npm info <package> peerDependencies
npm info <package> peerDependencies
npm 7+ auto-installs peer deps (may surprise you with version conflicts)
npm 7+会自动安装peer依赖项(可能因版本冲突导致意外)
Opt out: npm install --legacy-peer-deps (last resort)
选择退出:npm install --legacy-peer-deps(最后手段)
Check for peer dep conflicts
检查peer依赖冲突
npm install 2>&1 | grep "peer dep"
npm ls 2>&1 | grep "WARN" | grep "peer"
**Rule**: If you see peer dependency warnings, don't silence them. They indicate version mismatches that may cause subtle runtime failures. Resolve by pinning the common peer to a compatible version.
---npm install 2>&1 | grep "peer dep"
npm ls 2>&1 | grep "WARN" | grep "peer"
**规则**:如果看到peer依赖警告,不要忽略它们。这些警告表明版本不匹配,可能导致微妙的运行时故障。通过固定公共peer依赖项到兼容版本来解决问题。
---References
参考资料
- — Consult for Renovate vs Dependabot configuration details, grouping strategies, automerge policies, and testing update PRs safely
references/update-strategies.md - — Consult for npm audit / Snyk / Socket.dev deep dives, SBOM generation, license scanning tools, and CI integration patterns
references/security-auditing.md
- — 查阅Renovate与Dependabot的配置细节、分组策略、自动合并规则,以及安全测试更新PR的方法
references/update-strategies.md - — 查阅npm audit / Snyk / Socket.dev的深度解析、SBOM生成、许可证扫描工具,以及CI集成模式
references/security-auditing.md