Composer如何导出仅包含生产依赖的清单?(用于安全审计)

1次阅读

composer install –no-dev 不改变 composer.lock 中的 dev 依赖记录,安全审计需用 composer export –format=lock –without-dev 基于现有 lock 文件生成纯净生产环境依赖快照。

Composer如何导出仅包含生产依赖的清单?(用于安全审计)

composer install –no-dev 导出的 lock 文件不等于生产依赖清单

很多人以为 composer install --no-dev 能直接生成纯生产环境的依赖快照,其实它只是跳过 require-dev 的安装,并不会改变 composer.lock 里已记录的全部包(含 dev 包)。安全审计需要的是「不含任何开发依赖的、可验证的依赖树」,必须从 lock 文件中剥离 dev 信息重新生成。

用 composer show –no-dev -f json 输出纯净生产依赖树

composer show 默认输出所有已安装包,加 --no-dev 才真正过滤掉 require-dev 中声明的包(注意:不是“未安装”的包,而是“不在 require-dev 列表里的包”)。配合 -f json 可导出结构化数据,便于后续解析或上传到 SCA 工具。

  • 执行 composer show --no-dev -f json > prod-deps.json,得到仅含生产依赖的 JSON 清单
  • 该命令不依赖当前是否已运行 install,只要 composer.lock 存在就能读取依赖关系
  • 输出中每个包的 require 字段仍可能包含 dev-only 包(比如某个生产包间接依赖了 phpunit),但这种情况极少见;若需彻底排除传递性 dev 依赖,得用更重的方案(见下一条)

用 composer export –format=lock –without-dev 生成最小化 lock 子集

Composer 2.4+ 内置了 export 命令,专为审计场景设计。它不是简单过滤列表,而是基于 composer.lock 重建一个不含 require-dev 相关字段、且移除了所有 dev-only 包及其子依赖的新 lock 文件。

  • 运行 composer export --format=lock --without-dev > composer-prod.lock
  • 生成的 composer-prod.lock 可被 composer install --no-dev 正常消费,也能直接喂给 Dependabot、Snyk 等工具做比对
  • 注意:该命令要求 lock 文件中各包版本已解析完成(即至少执行过一次 composer installupdate),否则会报错 Lock file does not contain required packages
  • 如果项目用了 platform-check 或自定义 repositoriesexport 不会自动继承这些配置,需额外确认环境一致性

为什么不能直接删掉 composer.json 里的 require-dev 再 dump-autoload?

require-dev 后运行 composer update --lock 看似能“刷新” lock 文件,但实际风险很大:Composer 会重新计算整个依赖图,可能导致生产包版本漂移(比如原本靠 dev 包的约束锁住的某个次版本,现在松动升级了)。审计要的是「当前线上运行时的真实依赖快照」,不是「假设没 dev 时可能装出来的依赖」。

所以必须基于现有 composer.lock 做裁剪,而不是触发新的解析逻辑。这也是 export 比手动改 composer.json 更可靠的原因——它只做减法,不做重算。

真正容易被忽略的是:很多团队把 composer.lock 当作黑盒,却没意识到它的结构本身支持按角色切片。只要 Composer 版本够新,export 就是最轻量、最保真的方式。

text=ZqhQzanResources