Composer无--only/--exclude参数,精简依赖需用conflict硬拦截、replace静默替换或--no-dev隔离开发依赖,私有包须用type:package显式声明并置顶仓库顺序。

Composer 没有 --only 或 --exclude 这类运行时包名过滤命令,所有声称支持的 CLI 参数都不存在于官方实现中。想在复杂项目里精简依赖,必须绕过“过滤”幻觉,直击依赖解析机制本身。
用 conflict 在解析阶段硬拦截特定包
这是最确定、最轻量的排除方式:它不等下载或安装,就在求解依赖图时直接报错中断。
- 适用场景:已知某包(如
monolog/monolog)与当前 PHP 版本或自定义扩展冲突,且无法修改上游依赖 - 写法必须精确:
"conflict": { "monolog/monolog": ">=2.0.0" }—— 包名漏斜杠、版本通配不严谨都会失效 - 注意副作用:如果另一个你直接 require 的包(比如
symfony/console)硬依赖该包,整个composer update会失败,不是静默跳过 - 它对间接依赖无效:只拦最终进入
composer.lock的包,不拦中间传递链里被其他约束放行的版本
用 replace 静默“假装已有”,跳过安装
当你确认某个包实际没被代码调用,又不想触发 conflict 的强中断,replace 是更柔和的选择。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 典型用法:
"replace": { "phpunit/phpunit": "*" },告诉 Composer “这包我自有实现或根本不用”,它就不再尝试安装 - 风险点:如果多个依赖同时 require 它,而你的
replace版本号写得太死(如"1.2.0"),可能因版本不匹配引发 conflict 报错 -
replace不校验真实性——哪怕你 vendor 里真没这个包,Composer 也照常通过;上线前务必用composer show确认它确实没出现在已安装列表里 - 和
conflict不同,它不影响 autoload,所以即使被 replace,只要autoload-dev里还声明了路径,vendor/autoload.php仍可能包含其映射
靠 --no-dev 彻底隔离开发依赖
90% 的“冗余包”其实只是开发期工具,--no-dev 是生产部署唯一可靠开关。
-
composer install --no-dev会完全跳过require-dev区块,不解析、不下载、不写入vendor/,也不加载autoload-dev - 常见错误:只删
composer.json里的require-dev再跑install—— 没用,composer.lock仍存旧记录,install 会照单还原 - CI 脚本必须用
install --no-dev,而非update --no-dev:前者快、确定、不重算全图;后者仍会触发 solver 全局重分析,可能意外拉进新 dev 依赖 -
--no-dev对composer require无效;想临时加个 dev 包但不进 lock,得用composer require --dev --no-update
私有仓库必须用 "type": "package" 显式声明
想让私仓只提供几个指定包?别碰 "type": "composer" 仓库——它会全量扫描 packages.json,根本做不到白名单。
- 正确做法:每个私有包单独写成一个
"type": "package"条目,显式声明name、version和dist字段 - 顺序关键:把这类
package类型仓库放在repositories数组最前面,确保 Composer 优先匹配,避免被 packagist.org 同名包覆盖 - 错误示范:
"exclude": ["acme/*"]放在"type": "composer"仓库里——它只跳过当前源的查找,不阻止其他源(包括 packagist)提供同名包 - 一旦配置了任意非默认
repositories,Composer 就自动放弃校验“该包是否在 packagist.org 注册”,所以白名单逻辑只能靠显式声明,不能靠隐式过滤
真正难的不是写哪条命令,而是判断该用 conflict 中断、用 replace 绕过、还是用 package 类型仓库收口——三者作用环节不同,混用反而导致锁文件行为不可预测。每次改完配置,务必跑一次 composer update --dry-run 看 solver 实际选了什么,别信直觉。

















