audit-and-reduce-dependencies
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAudit and reduce dependencies
审计并缩减依赖
Reduce JavaScript dependency footprint. Use pnpm only. Preserve the lockfile, workspace layout, and dependency range style unless there is a concrete reason to change them.
For GitHub Actions workflow triage (action choice, permissions, pinning), use a dedicated workflow audit — not the reporting format below (workflow file + step only when the finding is pnpm install policy).
缩减JavaScript依赖占用空间。仅使用pnpm。保留锁定文件(lockfile)、工作区布局和依赖范围格式,除非有明确理由进行修改。
针对GitHub Actions工作流分类(操作选择、权限、固定版本),请使用专门的工作流审计工具——不要使用以下报告格式(仅当发现涉及pnpm安装策略时,才使用工作流文件+步骤的格式)。
Workflow
工作流程
- Hardening gate: run (read-only). See check-npm.
/check-npm - 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.
- 强化检查门:运行(只读)。查看check-npm。
/check-npm - 建立基准线。
- 移除未使用的直接依赖。
- 在单体仓库中去重直接依赖版本。
- 根据传递锁定文件闭包对直接依赖进行排序。
- 利用闭包数据找到低风险的小版本/补丁版本升级。
- 利用闭包数据找到值得内联的轻量依赖。
- 查看e18e的替换/移除建议。
- 重新安装、验证并报告实测影响。
Step 0: Hardening gate (/check-npm
)
/check-npm步骤0:强化检查门(/check-npm
)
/check-npmRun before mutating manifests or lockfiles.
/check-npm- If any check FAILs: report the table and fix snippets; do not weaken ,
pnpm-workspace.yaml, CI install flags, or Renovate age gates during cleanup..npmrc - Do not paste full hardening config into this workflow — owns version thresholds, script policy, git-dep protocols, and min release age.
/check-npm - If the user only asked for hardening (not reduction), stop after unless they also want cleanup.
/check-npm
pnpm 11+: script and release-age policy live in , not or (pnpm 11 no longer reads the field). Verify each key against the installed pnpm major before suggesting config. Never add unsupported keys. Do not lower an existing (or org equivalent) during cleanup.
pnpm-workspace.yaml.npmrcpackage.json#pnpmpackage.json#pnpmminimumReleaseAge在修改清单或锁定文件之前,先运行****。
/check-npm- 如果任何检查不通过:报告检查表格和修复代码段;在清理过程中不要弱化、
pnpm-workspace.yaml、CI安装标志或Renovate版本时限要求。.npmrc - 不要将完整的强化配置粘贴到本工作流程中——负责版本阈值、脚本策略、git依赖协议和最小发布时长的管理。
/check-npm - 如果用户仅要求强化(而非缩减),则在运行结束后停止操作,除非用户同时要求清理。
/check-npm
pnpm 11及以上版本:脚本和发布时长策略存储在中,而非或(pnpm 11不再读取字段)。在建议配置之前,需根据已安装的pnpm主版本验证每个配置项。切勿添加不支持的配置项。清理过程中不要降低现有的(或组织等效配置)。
pnpm-workspace.yaml.npmrcpackage.json#pnpmpackage.json#pnpmminimumReleaseAgeDependency triage
依赖分类
For each non-trivial direct dependency (especially after Steps 4–7), assign one label:
| Label | Meaning |
|---|---|
| Keep | Required; worthwhile transitive cost; well maintained. |
| Replace-with-Better | Required; better-maintained or safer alternative exists. |
| Replace-with-Internal | Required; external risk warrants internal implementation. |
| Remove | Can drop or inline (Step 6). |
| Needs-user-review | Ambiguous usage, policy tradeoff, or change needing human verification. |
Replacements and new direct deps
- No new direct dependencies (including swaps) without explicit user approval.
- Prefer Remove (inline/native APIs) over Replace-with-Better when equivalent.
- For Replace-with-Better: state why (maintenance, security, smaller tree); prefer actively maintained, widely adopted packages from trusted maintainers.
- Respect repo / Renovate gates; command-level 72h freshness is a floor, not permission to bypass stricter config.
minimumReleaseAge
对于每个非轻量直接依赖(尤其是步骤4-7之后),分配以下标签之一:
| 标签 | 含义 |
|---|---|
| Keep(保留) | 必需;传递依赖成本合理;维护状态良好。 |
| Replace-with-Better(替换为更优方案) | 必需;存在维护更完善或更安全的替代方案。 |
| Replace-with-Internal(替换为内部实现) | 必需;外部风险需要内部实现来规避。 |
| Remove(移除) | 可删除或内联(步骤6)。 |
| Needs-user-review(需用户审核) | 使用场景不明确、存在策略权衡或需要人工验证的变更。 |
替换与新增直接依赖
- 无明确用户批准,不得新增直接依赖(包括替换操作)。
- 当功能等效时,优先选择移除(内联/原生API)而非替换为更优方案。
- 对于替换为更优方案:说明原因(维护状态、安全性、依赖树更小);优先选择由可信维护者维护、被广泛采用且处于活跃维护状态的包。
- 遵守仓库的/Renovate时限要求;命令级别的72小时新鲜度是最低要求,并非绕过更严格配置的许可。
minimumReleaseAge
pnpm & supply-chain
pnpm与供应链
Confirm the repo uses pnpm: , , and/or / set to in root . If not on pnpm, stop — do not migrate package managers as part of cleanup.
pnpm-lock.yamlpnpm-workspace.yamlpackageManagerdevEngines.packageManager.namepnpmpackage.jsonRespect repo install policy when present (e.g. ).
pnpm install --frozen-lockfile --ignore-scripts| Action | Command |
|---|---|
| Install/update lockfile | |
| Remove direct dependency | |
| Add/update direct dependency | |
| Explain dependency | |
| Dedupe lockfile | |
| Outdated / version info | |
| One-off tools | |
Lifecycle scripts: Always on , , and unless the user explicitly writes allow scripts in the same message (state which scripts would run and the risk). For , does not accept directly — use (flags after are forwarded to the executed binary). If a dependency legitimately needs a build script (native modules, etc.), finish without scripts, then ask whether to run a specific manual rebuild (e.g. ).
--ignore-scriptspnpm installpnpm addpnpm removepnpm dlxdlx--ignore-scriptspnpm --config.ignore-scripts=true dlxdlxpnpm rebuild <pkg>Freshness check (≥ 72 hours) — required before any command that adds or upgrades a named package version (, with new/upgraded direct version). Not required for plain / with no new package argument.
pnpm addpnpm dlxpnpm installpnpm removeFor each directly named package:
curl -s https://registry.npmjs.org/<package-name>- Resolve version: pinned → that version; range/
pkg@1.2.3/unspecified →latestdist-tags.latest - Read
time["<version>"] - If published less than 72 hours ago → stop. Tell the user package, version, and exact age. Suggest an older known-good pin unless they write override freshness check.
- scoped packages are exempt from the freshness check;
@grafana/*still applies.--ignore-scripts
After a failed freshness check, do not substitute a different version without user approval.
确认仓库使用pnpm:存在、,且根目录中的/设置为。如果未使用pnpm,则停止操作——不要在清理过程中迁移包管理器。
pnpm-lock.yamlpnpm-workspace.yamlpackage.jsonpackageManagerdevEngines.packageManager.namepnpm若存在仓库安装策略(如),请严格遵守。
pnpm install --frozen-lockfile --ignore-scripts| 操作 | 命令 |
|---|---|
| 安装/更新锁定文件 | |
| 移除直接依赖 | |
| 添加/更新直接依赖 | |
| 解释依赖关系 | |
| 去重锁定文件 | |
| 过时/版本信息 | |
| 一次性工具 | |
生命周期脚本:在运行、和时,始终添加,除非用户在同一条消息中明确写明允许脚本(需说明将运行哪些脚本及其风险)。对于,不直接支持——需使用(之后的标志会转发给执行的二进制文件)。如果某个依赖确实需要构建脚本(如原生模块等),请先在禁用脚本的情况下完成操作,然后询问是否要运行特定的手动重建(如)。
pnpm installpnpm addpnpm remove--ignore-scriptspnpm dlxdlx--ignore-scriptspnpm --config.ignore-scripts=true dlxdlxpnpm rebuild <pkg>新鲜度检查(≥72小时)——在运行任何添加或升级指定包版本的命令(、带有新增/升级直接版本的)之前,必须执行此检查。无需执行的情况:不带新包参数的普通/。
pnpm addpnpm dlxpnpm installpnpm remove对于每个直接指定的包:
curl -s https://registry.npmjs.org/<package-name>- 解析版本:固定版本→ 该版本;范围/
pkg@1.2.3/未指定 →latestdist-tags.latest - 读取
time["<version>"] - 如果发布时长不足72小时 → 停止操作。告知用户包名、版本和精确发布时长。建议使用已知可用的旧版本固定,除非用户写明覆盖新鲜度检查。
- 作用域的包豁免新鲜度检查;
@grafana/*仍然适用。--ignore-scripts
新鲜度检查未通过后,未经用户批准不得替换为其他版本。
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 and lockfile dependency accounts.
package.json - Treat ,
peerDependencies, package bin usage, test fixtures, and published package manifests as higher risk.optionalDependencies - 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 switch package managers, delete , or rewrite workspace structure as part of cleanup.
pnpm-lock.yaml - Treat as potentially behavior-changing; inspect lockfile diffs and run focused verification before keeping the result.
pnpm dedupe - Measure before and after: direct dependency count, lockfile line count or entry count, package count, and estimated size when available.
node_modules
- 分批处理,确保锁定文件的差异可被审核。
- 不要盲目信任未使用依赖检测工具;需验证导入、配置文件、脚本、生成代码钩子、框架约定、插件名称、CLI和动态导入。
- 可编写脚本和解析逻辑来验证和锁定文件中的依赖情况。
package.json - 将、
peerDependencies、包二进制文件使用、测试 fixtures 和发布包清单视为高风险项。optionalDependencies - 除非替代方案被证明等效,否则不要移除或内联用于安全、解析、加密、Unicode、URL处理、日期/时间、国际化或平台兼容性的依赖。
- 不要在清理过程中切换包管理器、删除或重写工作区结构。
pnpm-lock.yaml - 需将视为可能改变行为的操作;在保留结果之前,需检查锁定文件差异并运行针对性验证。
pnpm dedupe - 前后对比测量:直接依赖数量、锁定文件行数或条目数、包数量,以及(若可用)的预估大小。
node_modules
Step 1: Baseline
步骤1:建立基准线
Collect:
- All files and workspace boundaries (
package.json).pnpm-workspace.yaml - ,
pnpm-lock.yamlsecurity settings (pnpm-workspace.yaml,minimumReleaseAge,strictDepBuilds,blockExoticSubdeps), and install policy inallowBuilds/ CI flags (e.g..npmrc,--frozen-lockfile).--ignore-scripts - Direct dependency names by manifest section: ,
dependencies,devDependencies,peerDependencies.optionalDependencies - Existing verification commands from scripts, CI, or repo docs.
- CI spot-check (or equivalent): installs should use
.github/workflowsand script blocking consistent with workspace config. Flag workflows that regenerate lockfiles on every run.pnpm install --frozen-lockfile - Renovate / Dependabot (if present): note for npm packages; do not reduce it during cleanup.
minimumReleaseAge
Record baseline metrics: , . If is installed, estimate footprint with platform-appropriate tools. Lockfile reductions are the primary metric — do not depend on being present.
git status --shortwc -l pnpm-lock.yamlnode_modulesnode_modules收集以下信息:
- 所有文件和工作区边界(
package.json)。pnpm-workspace.yaml - 、
pnpm-lock.yaml的安全设置(pnpm-workspace.yaml、minimumReleaseAge、strictDepBuilds、blockExoticSubdeps),以及allowBuilds/CI标志中的安装策略(如.npmrc、--frozen-lockfile)。--ignore-scripts - 按清单分类的直接依赖名称:、
dependencies、devDependencies、peerDependencies。optionalDependencies - 来自脚本、CI或仓库文档的现有验证命令。
- CI抽查(或等效目录):安装操作应使用
.github/workflows,且脚本拦截需与工作区配置一致。标记每次运行都会重新生成锁定文件的工作流。pnpm install --frozen-lockfile - Renovate / Dependabot(若存在):记录npm包的;清理过程中不要降低该值。
minimumReleaseAge
记录基准指标:、。若已安装,使用平台适配工具预估其占用空间。锁定文件缩减量是主要指标——不要依赖是否存在。
git status --shortwc -l pnpm-lock.yamlnode_modulesnode_modulesStep 2: Remove unused direct dependencies
步骤2:移除未使用的直接依赖
Unsafe direct dependency protocols — scan all workspace dependency sections. Flag values that are not: semver range, , , or alias to semver. Flag / / tarball URLs / shorthand / / / / etc. (same allow-list as ). Do not remove flagged entries silently; report for a separate hardening PR unless the user asked to fix them.
package.jsonworkspace:patch:npm:git:github:user/repofile:link:exec:/check-npmUse a static analyzer as a starting point, not as proof (knip, depcheck, or repo-native tooling). Run with pinned when not installed (freshness-check the pin first).
pnpm --config.ignore-scripts=true dlx <tool>@<version> <args...>For each candidate:
- Search code, configs, package scripts, build tooling, tests, and docs for the package name and known import paths.
- Check whether required by a published package manifest, peer contract, plugin loader, CLI command, or dynamic /
require.import - Remove only when no real usage remains.
- Run (+ repo flags) and focused verification.
pnpm install --ignore-scripts
If usage is only in a script or config, consider moving between and instead of removing.
dependenciesdevDependencies不安全的直接依赖协议——扫描所有工作区的依赖部分。标记不符合以下类型的值:语义化版本范围、、、或指向语义化版本的别名。标记//压缩包URL/简写///等(与的允许列表一致)。不要静默移除标记项;除非用户要求修复,否则应单独提交强化PR进行处理。
package.jsonworkspace:patch:npm:git:github:user/repofile:link:exec:/check-npm使用静态分析工具作为起点(而非最终依据),如knip、depcheck或仓库原生工具。若未安装,使用固定版本运行(先对固定版本进行新鲜度检查)。
pnpm --config.ignore-scripts=true dlx <tool>@<version> <args...>对于每个候选依赖:
- 在代码、配置、包脚本、构建工具、测试和文档中搜索包名和已知导入路径。
- 检查是否为发布包清单、对等依赖约定、插件加载器、CLI命令或动态/
require所必需。import - 仅当确认无实际使用时才移除。
- 运行(加上仓库标志)并进行针对性验证。
pnpm install --ignore-scripts
若仅在脚本或配置中使用,可考虑在和之间移动,而非移除。
dependenciesdevDependenciesStep 3: Deduplicate monorepo direct versions
步骤3:单体仓库直接版本去重
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.
- Use or equivalent for discovery.
syncpack list-mismatches - Standardize direct ranges when packages can share the same compatible version.
- Prefer manifest-level consistency before adding .
pnpm.overrides - Use only for transitive convergence or security fixes, and document why.
pnpm.overrides
After deduping, run (+ repo flags) and inspect manifest and lockfile diffs. Then consider — apply carefully; may change transitive resolution.
pnpm install --ignore-scriptspnpm dedupe查找在多个包清单中以不同版本/范围声明的同一直接依赖。优先使用现有策略:精确固定版本、 caret 范围、目录/协议使用、工作区协议或集中约束。
- 使用或等效工具进行发现。
syncpack list-mismatches - 当包可共享兼容版本时,统一直接依赖范围。
- 在添加之前,优先保证清单级别的一致性。
pnpm.overrides - 仅在需要收敛传递依赖或修复安全问题时使用,并说明原因。
pnpm.overrides
去重后,运行(加上仓库标志)并检查清单和锁定文件的差异。然后考虑运行——需谨慎操作;可能会改变传递依赖解析结果。
pnpm install --ignore-scriptspnpm dedupeStep 4: Rank transitive lockfile closure
步骤4:对传递锁定文件闭包排序
For each important direct dependency, estimate closure: transitive lockfile entries reachable from that 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:
- Save baseline lockfile metrics.
- Temporarily remove one direct dependency from the owning manifest.
- Run (+ repo flags).
pnpm install --ignore-scripts - Measure lockfile line/entry reduction and package count reduction.
- Revert the manifest and (e.g.,
pnpm-lock.yaml) before measuring the next dependency.git checkout -- <manifest> pnpm-lock.yaml
Use for large transitive packages. Rank by impact and risk, not just raw size.
pnpm why <pkg>对于每个重要的直接依赖,估算其闭包:从该依赖可到达的传递锁定文件条目。
报告以下两项:
- 总闭包:从该依赖可到达的所有包。
- 专属闭包:移除该依赖后会消失且不被其他直接依赖保留的包。
优先使用确定性测量方法:
- 保存基准锁定文件指标。
- 临时从所属清单中移除一个直接依赖。
- 运行(加上仓库标志)。
pnpm install --ignore-scripts - 测量锁定文件行数/条目减少量和包数量减少量。
- 在测量下一个依赖之前,还原清单和(如
pnpm-lock.yaml)。git checkout -- <manifest> pnpm-lock.yaml
对于大型传递依赖,使用查看依赖关系。按影响和风险排序,而非仅按原始大小。
pnpm why <pkg>Step 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 .
pnpm outdated - Review changelog/release notes for dependency tree changes.
- Freshness-check the target version, then upgrade one dependency or tight cluster at a time ().
pnpm add <pkg>@<version> --ignore-scripts - Run (+ repo flags) and compare closure metrics.
pnpm install --ignore-scripts - Run focused tests and relevant build/typecheck commands.
Avoid major upgrades unless the user explicitly accepts the migration risk.
利用闭包排序结果,针对其新版本(小版本/补丁版本)可减少传递依赖的直接依赖进行升级。
对于每个候选依赖:
- 使用查看可用的非主版本。
pnpm outdated - 查看变更日志/发行说明,了解依赖树的变化。
- 对目标版本进行新鲜度检查,然后一次升级一个依赖或一组紧密关联的依赖()。
pnpm add <pkg>@<version> --ignore-scripts - 运行(加上仓库标志)并对比闭包指标。
pnpm install --ignore-scripts - 运行针对性测试和相关构建/类型检查命令。
除非用户明确接受迁移风险,否则避免主版本升级。
Step 6: Inline trivial usage
步骤6:内联轻量使用的依赖
Use closure rankings to find direct dependencies with small, obvious usage 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指导
bash
undefinedbash
undefinedPin @e18e/cli@<version> after freshness check; disable scripts on the dlx install
新鲜度检查后固定@e18e/cli@<version>;在dlx安装时禁用脚本
pnpm --config.ignore-scripts=true dlx @e18e/cli@<version> analyze
pnpm --config.ignore-scripts=true dlx @e18e/cli@<version> migrate --dry-run
Also check https://e18e.dev/docs/replacements/. Treat recommendations as candidates, not mandates; verify bundle/runtime behavior and run tests. Map e18e swaps to **Replace-with-Better** only after user approval.pnpm --config.ignore-scripts=true dlx @e18e/cli@<version> analyze
pnpm --config.ignore-scripts=true dlx @e18e/cli@<version> migrate --dry-run
同时查看https://e18e.dev/docs/replacements/。将建议视为候选方案,而非强制要求;需验证打包/运行时行为并运行测试。仅在获得用户批准后,将e18e的替换映射为**替换为更优方案**。Reporting
报告
Summarize outcomes with measured impact:
- result (PASS/FAIL summary; link fixes if FAIL).
/check-npm - 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 (including replacements awaiting approval).
- Unsafe protocol / CI / Renovate findings from baseline (if any).
- Verification commands run and results.
- Supply-chain: versions freshness-checked (or exempted), on all installs/adds,
--ignore-scriptson--config.ignore-scripts=true.pnpm dlx
Call out risk explicitly when a removal depends on static analysis rather than runtime coverage.
总结结果并说明实测影响:
- 结果(通过/不通过摘要;若不通过,链接修复方案)。
/check-npm - 移除或移动的直接依赖。
- 去重的直接依赖版本。
- 锁定文件行数/条目减少量。
- (若可用)预估的包或缩减量。
node_modules - 推迟处理的高影响候选方案及原因(包括等待批准的替换项)。
- 基准检查中发现的不安全协议/CI/Renovate问题(若有)。
- 运行的验证命令及结果。
- 供应链:经过新鲜度检查(或豁免)的版本、所有安装/添加操作均使用、
--ignore-scripts使用pnpm dlx。--config.ignore-scripts=true
当移除操作仅基于静态分析而非运行时覆盖时,需明确指出风险。
Reporting format
报告格式
Use for dependency cleanup findings only — not GitHub Actions workflow triage.
For each finding:
- Evidence: package name and version/range; manifest path and section; supporting signal (import site, , knip/depcheck hit, closure measurement,
pnpm whyrow, or workflow file + step only for pnpm install policy)./check-npm - Decision: one of Dependency triage labels.
- Proposed change: exact manifest/lockfile command or edit. If not applied yet, state that explicitly.
- Rationale: footprint (exclusive/total closure), supply-chain, maintenance, or verification risk.
- User review required: tests/build/typecheck to run; peer/plugin/CLI consumers; published-package or dynamic-import risk; approval before Replace-with-Better or any new direct dependency.
Use one block per package (or per protocol/CI finding), not a single-line summary, when the finding is non-trivial.
仅用于依赖清理发现——不适用于GitHub Actions工作流分类。
对于每个发现:
- 证据:包名和版本/范围;清单路径和分类;支持信号(导入位置、结果、knip/depcheck命中、闭包测量结果、
pnpm why行、或仅当涉及pnpm安装策略时的工作流文件+步骤)。/check-npm - 决策:依赖分类标签之一。
- 建议变更:精确的清单/锁定文件命令或编辑。若尚未应用,需明确说明。
- 理由:占用空间(专属/总闭包)、供应链、维护状态或验证风险。
- 需用户审核:需运行的测试/构建/类型检查;对等依赖/插件/CLI消费者;发布包或动态导入风险;替换为更优方案或任何新增直接依赖需获得批准。
当发现内容非轻量级时,每个包(或每个协议/CI发现)使用一个区块,而非单行摘要。",