composer install 不支持 --only、--exclude、--filter 等包过滤参数;唯一可靠精简方式是 --no-dev(跳过开发依赖),配合 conflict(解析期拦截)、archive.excludes(解压期过滤)和版本锁定实现裁剪。

composer install 没有 --only、--exclude、--filter 这类运行时包名过滤参数——所有声称支持的 CLI 选项都不存在于 Composer 官方实现中。想控制装什么、不装什么,必须绕过“过滤”这个错误前提,直接干预依赖解析或安装行为本身。
用 --no-dev 跳过开发依赖(最常用且必须)
这是生产部署唯一可靠、必须加的开关,它不解析、不下载、不写入 vendor/ 中任何 require-dev 声明的包。
-
composer install --no-dev是安全底线;CI/CD 漏掉它,vendor 体积多出 30%~60%,还可能因 autoload-dev 映射残留引发Class not found -
--no-dev不影响autoload-dev的 PSR-4 声明,但那些路径根本不会被解压到vendor/,所以实际不会加载 - 别删
require-dev后再跑install——没用。composer.lock里仍存旧记录,会照单还原 -
composer update --no-dev会清掉已安装的 dev 包,但不会重写lock文件中的 dev 记录,不可替代install --no-dev
用 conflict 在解析阶段硬拦截特定包
它不是“跳过”,而是在依赖求解时就报错中断,确保某包绝不会进入 composer.lock。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 写法必须精确:
"conflict": { "monolog/monolog": ">=3.0.0" }——包名漏斜杠、版本通配不严谨(如写成*)都会失效 - 副作用明显:如果另一个你
require的包(比如symfony/console)硬依赖该包,整个composer update会失败,不是静默跳过 - 它只拦最终进入
lock的包,对中间传递链里被其他约束放行的版本无效 - 适用于已知兼容性冲突且无法修改上游依赖的场景,比如 PHP 版本升级后某包不兼容
用 archive.excludes 在解压时过滤包内冗余路径
--no-dev 和 --prefer-dist 解决不了的问题——比如 monolog/monolog 的 tests/Handlers/ 示例代码,它被打包进了 zip,得在 unzip 阶段跳过。
- 先装插件:
composer require --dev composer-archive-excludes - 在
composer.json的config.archive.excludes下加项:["/tests/", "/docs/", "/examples/", "/.github/"] - 注意路径开头带
/,否则匹配不生效;/tests/会匹配vendor/monolog/monolog/tests/,但不会误伤test-utils - 别手动
find vendor -name tests -exec rm -rf {} +——旧版monolog把StreamHandler示例放在tests/下,删了会导致运行时报Class not found
别信 --ignore 能当过滤用
composer update --ignore=xxx(≥2.2 支持)只是临时跳过单次更新,不是排除,更不阻止间接依赖拉入。
- 它只冻结目标包自身版本,不处理其子依赖;若
symfony/console强依赖monolog/monolog ^3.0,而你没锁死symfony/console,monolog仍会被连带升级 - 多个包要重复写多次
--ignore,不能合并成--ignore=a,b - 低版本 Composer 会直接报
Unrecognized option "--ignore",别硬试 - 真正永久冻结,是把版本号写死(如
"monolog/monolog": "2.9.1"),再composer update monolog/monolog并提交composer.lock
复杂点在于:所有“精简”动作都相互耦合。比如用了 archive.excludes 却没开 --classmap-authoritative,autoloader 仍可能因 scandir 失败报错;又比如 conflict 写得过宽,导致整个依赖图无法求解。最容易被忽略的是——composer install 从不读取 require-dev 以外的任何“过滤意图”,它只忠实地还原 composer.lock,所以所有裁剪必须发生在 lock 生成前,或靠 --no-dev 这种安装期开关兜底。










