prefer-stable 是版本排序偏好而非开关,仅在满足 minimum-stability 且多版本候选时优先选最稳定版;必须与 "minimum-stability": "stable" 配合使用,并运行 composer update --lock 才生效。

prefer-stable 不是开关,而是“排序偏好”
prefer-stable 的作用非常具体:当多个版本都满足你的版本约束(比如 ^2.0),且都符合当前 minimum-stability 底线时,它会让 Composer 优先挑其中最稳定的那个——比如在 2.0.0(stable)、2.1.0-beta.1(beta)、2.1.x-dev(dev)里选 2.0.0。但它不会拦住你写死的 "monolog/monolog": "dev-main",也不会把已锁在 composer.lock 里的 dev 版本“踢出去”。
- 它只影响「同一约束下的候选排序」,不是过滤器
- 必须放在
composer.json的顶层,不是config下面——放错位置就完全不生效 - 单独设
"prefer-stable": true没用,一定要配"minimum-stability": "stable"才能真正挡住 beta/dev - 如果某个依赖自己写了
"minimum-stability": "dev",它的子依赖可能绕过你的偏好,得靠require显式加@stable卡住
怎么正确启用 prefer-stable(项目级)
推荐只在项目里设,避免全局污染其他项目。改 composer.json,确保结构是这样:
{
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"monolog/monolog": "^2.0"
}
}
- 删掉旧配置里误塞进
"config": { "prefer-stable": true }的写法——那根本没用 - 改完后必须运行
composer update --lock,否则composer.lock还是旧策略下的结果 - 如果之前装过
dev版,光composer install不会换;得composer update monolog/monolog或全量更新 - 临时想试效果?加命令行参数:
composer update --prefer-stable,但别依赖它长期用
为什么装了 prefer-stable 还有 dev 包?
常见原因就三个,按发生频率排:
- 你在
require里写了"vendor/package": "dev-main"或"dev-develop"——Composer 把这当明确指令,直接执行,无视所有偏好 - 某个依赖包自己的
composer.json设了"minimum-stability": "dev",又没设"prefer-stable": true,它的下游依赖就可能带出dev版 -
composer.lock里已经锁死了dev版本,而你只跑composer install——它根本不重新算版本,照着 lock 装
验证是否真生效?删掉 vendor 和 composer.lock,再 composer install 看装出来的是不是稳定版。
minimum-stability 和 prefer-stable 怎么配合用
minimum-stability 是底线,prefer-stable 是口味。比如设 "minimum-stability": "beta",Composer 就允许装 beta/RC/stable;再加 "prefer-stable": true,它就会在这些里面优先挑 stable,而不是随便抓个 beta 就上。
- 生产环境强烈建议
"minimum-stability": "stable"+"prefer-stable": true - 测试环境想尝新?可设
"minimum-stability": "RC",但依然保留"prefer-stable": true,避免意外装到alpha或dev - 注意:
RC必须全大写,写成rc或Rc会被忽略,退回到默认stable - 单个包要破例?用后缀:
"monolog/monolog": "2.10.0@beta",它会覆盖全局设置
最常被忽略的一点:改完配置后,不运行 composer update --lock,等于没改——因为锁文件不更新,所有安装行为都按旧策略走。











