npm-deps-cleanup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesenpm Dependency Cleanup
npm依赖清理
Reduce JavaScript dependency footprint. Preserve the existing package manager, lockfile, workspace layout, and dependency range style unless there is a concrete reason to change them.
减少JavaScript依赖占用空间。除非有明确理由,否则保留现有包管理器、lockfile、工作区布局和依赖范围格式。
Workflow
工作流程
- Establish the baseline.
- Remove unused direct dependencies.
- Deduplicate direct dependency versions in monorepos.
- Rank direct dependencies by transitive lockfile closure.
- Use closure data to find low-risk minor/patch upgrades.
- Use closure data to find trivial dependencies worth inlining.
- Check e18e recommendations for replacements/removals.
- Reinstall, verify, and report measured impact.
- 建立基准。
- 移除未使用的直接依赖。
- 统一 monorepo 中的直接依赖版本。
- 根据传递性lockfile闭包对直接依赖排序。
- 利用闭包数据寻找低风险的小版本/补丁版本升级。
- 利用闭包数据寻找值得内联的轻量依赖。
- 检查e18e的替换/移除建议。
- 重新安装、验证并报告实测影响。
Package Manager Detection
包管理器检测
Use the repo's existing package manager. Prefer explicit package metadata before lockfiles:
- in the root
packageManager.package.json - in the root
devEngines.packageManager.name.package.json - Lockfile inference.
When is present, use its for npm, pnpm, Yarn, or Bun detection. Treat its and fields as policy signals, not as permission to change package managers.
devEngines.packageManagernameversiononFailInfer from lockfiles only when package metadata does not identify the package manager:
| Signal | Package manager |
|---|---|
| npm |
| pnpm |
| Yarn |
| Bun |
Use the matching command family:
| Action | npm | pnpm | Yarn | Bun |
|---|---|---|---|---|
| Install/update lockfile | | | | |
| Remove direct dependency | | | | |
| Add/update direct dependency | | | | |
| Explain dependency | | | | |
| Dedupe lockfile | | | | reinstall and inspect |
| One-off tools | | | | |
使用仓库现有的包管理器。优先依据明确的包元数据,而非lockfile:
- 根目录中的
package.json字段。packageManager - 根目录中的
package.json字段。devEngines.packageManager.name - 通过lockfile推断。
当存在时,使用其字段检测npm、pnpm、Yarn或Bun。将其和字段视为策略信号,而非更改包管理器的许可。
devEngines.packageManagernameversiononFail仅当包元数据无法识别包管理器时,才通过lockfile推断:
| 信号 | 包管理器 |
|---|---|
| npm |
| pnpm |
| Yarn |
| Bun |
使用对应的命令集:
| 操作 | npm | pnpm | Yarn | Bun |
|---|---|---|---|---|
| 安装/更新lockfile | | | | |
| 移除直接依赖 | | | | |
| 添加/更新直接依赖 | | | | |
| 解释依赖 | | | | |
| 去重lockfile | | | | 重新安装并检查 |
| 一次性工具 | | | | |
Safety Rules
安全规则
- Work in small batches so lockfile diffs remain reviewable.
- Never trust unused-dependency tools blindly; verify imports, config files, scripts, generated code hooks, framework conventions, plugin names, CLIs, and dynamic imports.
- You may write scripting and parsing to verify package.json and lockfile dependency accounts.
- Treat ,
peerDependencies, packageoptionalDependenciesusage, test fixtures, and published package manifests as higher risk.bin - Do not remove or inline dependencies used for security, parsing, crypto, Unicode, URL handling, date/time, i18n, or platform compatibility unless the replacement is proven equivalent.
- Do not change package managers, delete lockfiles, or rewrite workspace structure as part of cleanup.
- Treat package manager dedupe commands as potentially behavior-changing. They can alter selected transitive versions within allowed ranges, so inspect lockfile diffs and run focused verification before keeping the result.
- Measure before and after: direct dependency count, lockfile line count or entry count, package count, and estimated size when available.
node_modules
- 分批处理,确保lockfile的差异可被评审。
- 不要盲目信任未使用依赖检测工具;需验证导入、配置文件、脚本、生成代码钩子、框架约定、插件名称、CLI和动态导入。
- 可编写脚本和解析逻辑来验证package.json和lockfile中的依赖情况。
- 将、
peerDependencies、包的optionalDependencies用法、测试 fixtures 和已发布包清单视为高风险项。bin - 除非能证明替代方案等效,否则不要移除或内联用于安全、解析、加密、Unicode、URL处理、日期/时间、国际化(i18n)或平台兼容性的依赖。
- 不要在清理过程中更改包管理器、删除lockfile或重写工作区结构。
- 包管理器的去重命令可能会改变行为。它们可能会在允许的范围内更改选定的传递依赖版本,因此在保留结果前需检查lockfile差异并进行针对性验证。
- 前后对比测量:直接依赖数量、lockfile行数或条目数、包数量,以及(若可用)的预估大小。
node_modules
Step 1: Baseline
步骤1:建立基准
Collect:
- All files and workspace boundaries.
package.json - Current package manager and lockfile.
- Direct dependency names by manifest section: ,
dependencies,devDependencies,peerDependencies.optionalDependencies - Existing verification commands from scripts, CI, or repo docs.
Record baseline metrics before edits:
sh
git status --short
wc -l <lockfile>If is installed, also estimate installed footprint with platform-appropriate filesystem tools. Do not make footprint cleanup depend on being present; lockfile reductions are the primary metric.
node_modulesnode_modules收集:
- 所有文件和工作区边界。
package.json - 当前包管理器和lockfile。
- 按清单分类的直接依赖名称:、
dependencies、devDependencies、peerDependencies。optionalDependencies - 来自脚本、CI或仓库文档的现有验证命令。
在编辑前记录基准指标:
sh
git status --short
wc -l <lockfile>若已安装,也可使用平台适配的文件系统工具预估安装后的占用空间。不要依赖的存在来完成占用空间清理;lockfile的缩减是主要指标。
node_modulesnode_modulesStep 2: Remove Unused Direct Dependencies
步骤2:移除未使用的直接依赖
Use a static analyzer as a starting point, not as proof. Good candidates include , , or repo-native tooling if already configured. Run them through the detected package manager's one-off executor when they are not installed.
knipdepcheckFor each candidate:
- Search code, configs, package scripts, build tooling, tests, and docs for the package name and known import paths.
- Check whether the dependency is required by a published package manifest, peer contract, plugin loader, CLI command, or dynamic require/import.
- Remove only when no real usage remains.
- Reinstall with the detected package manager and run focused verification.
If usage is only in a script or config, consider moving between and instead of removing.
dependenciesdevDependencies将静态分析工具作为起点,而非最终依据。合适的工具包括、,或仓库已配置的原生工具。若工具未安装,通过检测到的包管理器的一次性执行器运行它们。
knipdepcheck针对每个候选依赖:
- 在代码、配置、包脚本、构建工具、测试和文档中搜索包名称及已知导入路径。
- 检查该依赖是否为已发布包清单、peer契约、插件加载器、CLI命令或动态require/import所必需。
- 仅当确认无实际使用时才移除。
- 使用检测到的包管理器重新安装并进行针对性验证。
若仅在脚本或配置中使用,可考虑在和之间移动,而非直接移除。
dependenciesdevDependenciesStep 3: Deduplicate Monorepo Direct Versions
步骤3:统一Monorepo直接依赖版本
In monorepos, look for the same direct dependency declared with multiple versions/ranges across package manifests. Use existing policy first: exact pins, caret ranges, catalog/protocol usage, workspace protocol, or central constraints.
Good approaches:
- Use or equivalent package-manager-neutral tooling for discovery.
syncpack list-mismatches - Standardize direct ranges when packages can share the same compatible version.
- Prefer manifest-level consistency before adding overrides/resolutions.
- Use overrides/resolutions only for transitive dependency convergence or security fixes, and document why.
After deduping, reinstall and inspect both manifest and lockfile diffs.
Then consider the package manager's native lockfile dedupe command: , , or when available. Bun has no direct equivalent; run and inspect whether the lockfile converges. Apply these commands carefully because they may change transitive dependency resolution and introduce breakage even without manifest edits.
npm dedupepnpm dedupeyarn dedupebun install在monorepo中,查找在多个包清单中以不同版本/范围声明的相同直接依赖。优先遵循现有策略:精确固定版本、脱字符范围、目录/协议用法、工作区协议或集中约束。
合适的方法:
- 使用或等效的跨包管理器工具进行发现。
syncpack list-mismatches - 当包可共享兼容版本时,统一直接依赖范围。
- 在添加覆盖/解析规则前,优先保证清单层面的一致性。
- 仅为传递依赖收敛或安全修复使用覆盖/解析规则,并记录原因。
统一版本后,重新安装并检查清单和lockfile的差异。
随后可考虑使用包管理器原生的lockfile去重命令:、或(若可用)。Bun无直接等效命令;运行并检查lockfile是否收敛。谨慎使用这些命令,因为它们可能会改变传递依赖的解析结果,即使不修改清单也可能引入问题。
npm dedupepnpm dedupeyarn dedupebun installStep 4: Rank Transitive Lockfile Closure
步骤4:排序传递性Lockfile闭包
For each important direct dependency, estimate its closure: the set of transitive lockfile entries reachable from that direct dependency.
Report both:
- Total closure: all packages reachable from the dependency.
- Exclusive closure: packages that disappear if this dependency is removed and are not retained by other direct dependencies.
Prefer deterministic measurement over guesses. Package-manager-neutral fallback:
- Save baseline lockfile metrics.
- Temporarily remove one direct dependency from the owning manifest.
- Run the detected package manager install.
- Measure lockfile line/entry reduction and package count reduction.
- Revert the temporary removal before measuring the next dependency.
Use , , , or available package-manager graph commands to understand why large transitive packages exist. Rank dependencies by impact and risk, not just raw size.
npm explainpnpm whyyarn why针对每个重要的直接依赖,预估其闭包:即从该直接依赖可到达的所有传递性lockfile条目集合。
需报告两项内容:
- 总闭包:从该依赖可到达的所有包。
- 专属闭包:移除该依赖后会消失且未被其他直接依赖保留的包。
优先采用确定性测量而非猜测。跨包管理器的 fallback 方法:
- 保存基准lockfile指标。
- 临时从所属清单中移除一个直接依赖。
- 运行检测到的包管理器安装命令。
- 测量lockfile行数/条目数的减少量以及包数量的减少量。
- 在测量下一个依赖前,撤销临时移除操作。
使用、、或可用的包管理器图谱命令,理解大型传递依赖存在的原因。按影响和风险对依赖排序,而非仅按原始大小。
npm explainpnpm whyyarn whyStep 5: Find Low-Risk High-Impact Upgrades
步骤5:寻找低风险高影响的升级
Use closure rankings to target direct dependencies whose newer minor/patch versions reduce transitive dependencies.
For each candidate:
- Check available non-major versions with the package manager's outdated/info commands.
- Review changelog/release notes for dependency tree changes and compatibility notes.
- Upgrade one dependency or tight cluster at a time.
- Reinstall and compare closure metrics before/after.
- Run focused tests and relevant build/typecheck commands.
Avoid major upgrades unless the user explicitly accepts the migration risk.
利用闭包排序结果,针对其新版本(小版本/补丁版本)可减少传递依赖的直接依赖进行升级。
针对每个候选依赖:
- 使用包管理器的outdated/info命令检查可用的非主版本。
- 查看变更日志/发布说明,了解依赖树的变化和兼容性说明。
- 一次升级一个依赖或一组紧密关联的依赖。
- 重新安装并对比升级前后的闭包指标。
- 运行针对性测试及相关构建/类型检查命令。
除非用户明确接受迁移风险,否则避免主版本升级。
Step 6: Inline Trivial Usage
步骤6:内联轻量依赖
Use closure rankings to find direct dependencies with small, obvious usage in the codebase but large transitive cost.
Inline only when all are true:
- Usage is tiny and easy to fully characterize.
- Equivalent code is shorter or clearer than retaining the dependency.
- Behavior is covered by tests or can be covered with small characterization tests.
- The dependency is not solving cross-platform, security, parsing, Unicode, locale, or spec-compliance edge cases.
Prefer native APIs over new replacement dependencies when the required behavior is simple.
利用闭包排序结果,找到在代码库中使用量极小但传递成本极高的直接依赖。
仅当满足以下所有条件时才进行内联:
- 使用量极小,可完全明确其用途。
- 等效代码比保留依赖更简短或清晰。
- 行为已被测试覆盖,或可通过小型特性测试覆盖。
- 该依赖未解决跨平台、安全、解析、Unicode、本地化或规范兼容的边缘情况。
当所需行为简单时,优先使用原生API而非新的替代依赖。
Step 7: Apply e18e Guidance
步骤7:应用e18e指导
Consult e18e for additional removal and replacement candidates:
sh
<runner> @e18e/cli analyze
<runner> @e18e/cli migrate --dry-runReplace with the detected one-off executor: , , , or .
<runner>npxpnpm dlxyarn dlxbunxAlso check the e18e module replacements list at for known alternatives. Treat recommendations as candidates, not mandates; verify bundle/runtime behavior and run tests.
https://e18e.dev/docs/replacements/参考e18e获取更多移除和替换候选项:
sh
<runner> @e18e/cli analyze
<runner> @e18e/cli migrate --dry-run将替换为检测到的一次性执行器:、、或。
<runner>npxpnpm dlxyarn dlxbunx同时查看e18e模块替换列表,了解已知替代方案。将建议视为候选而非强制要求;需验证打包/运行时行为并执行测试。
https://e18e.dev/docs/replacements/Reporting
报告
Summarize outcomes with measured impact:
- Direct dependencies removed or moved.
- Direct versions deduplicated.
- Lockfile line/entry reduction.
- Estimated package or reduction when available.
node_modules - High-impact candidates deferred and why.
- Verification commands run and results.
Call out risk explicitly when a removal depends on static analysis rather than runtime coverage.
总结成果并说明实测影响:
- 移除或移动的直接依赖。
- 统一的直接依赖版本。
- Lockfile行数/条目数的减少量。
- (若可用)预估的包数量或减少量。
node_modules - 暂缓处理的高影响候选项及原因。
- 执行的验证命令及结果。
当依赖移除仅基于静态分析而非运行时覆盖时,需明确标注风险。