minimum-stability 是 composer 的全局稳定性筛选门槛,默认为 stable,设为 dev 会导致所有依赖可能降级到不可控的开发版本;应优先通过 require 显式指定 dev 版本,并配合 prefer-stable=true 保障稳定性。

minimum-stability 是什么,为什么不能随便设成 dev
minimum-stability 是 composer.json 里的一个根级配置项,它不是“最低要求”,而是全局默认的包稳定性筛选门槛。Composer 默认只允许安装 stable 版本(即没有 -dev、-alpha、-beta、-rc 后缀的版本)。设成 dev 后,所有依赖(包括你没显式指定版本的间接依赖)都可能被降级到开发分支,导致不可控的 break change。
- 常见错误现象:
composer require some/package报错 “Could not find package… or could not find a version matching…” —— 实际是目标包只有dev-main或dev-feature/x分支,但你的minimum-stability是stable - 真正该用的场景:仅当你明确需要某个包的开发版(比如等官方发版前临时用 PR 分支),且已通过
require显式锁死具体分支或dev-版本时,才考虑调低这个值 - 不要把它当成“解决找不到包”的万能开关;更安全的做法是局部覆盖,而不是全局放宽
怎么安全地让某个包用 dev 版本(推荐做法)
比起改 minimum-stability,优先用 require 中的版本约束直接指定不稳定版本。Composer 会按“最具体优先”原则,让这条规则覆盖全局 minimum-stability。
- 想装 GitHub 上某仓库的 main 分支:
"vendor/name": "dev-main" - 想装某个 commit:
"vendor/name": "dev-main#abc1234" - 想装带
-dev后缀的预发布版:"vendor/name": "2.0.x-dev" - 注意:如果包本身没打任何 tag,又没配置
repositories指向 VCS 源,Composer 就查不到dev-分支 —— 这时候光改minimum-stability也没用
如果真要改 minimum-stability,必须同步配 prefer-stable
设 "minimum-stability": "dev" 后,所有包都可能拉 dev- 版,连 monolog/monolog 都可能变成 dev-main。这不是你想要的。所以必须加 "prefer-stable": true,它会让 Composer 在满足约束的前提下,**优先选 stable 版本**,只在没 stable 可选时才退到更低稳定性。
- 正确写法(放在
composer.json根对象里):"minimum-stability": "dev", "prefer-stable": true
- 不配
prefer-stable的后果:CI 构建结果每天都不一样,本地能跑线上炸了,因为随机拉到了不同 commit 的 dev 分支 -
prefer-stable不影响你显式 require 的dev-版本,它只作用于“未显式指定稳定性”的依赖
稳定性和版本约束冲突时,Composer 怎么选
Composer 的版本解析是分两步走的:先根据 minimum-stability 过滤出合法候选集,再在其中匹配你写的版本约束(如 ^2.0)。所以 "minimum-stability": "stable" 时,"vendor/name": "^2.0" 就永远不可能命中 2.0.x-dev —— 它根本不在候选集里。
- 常见陷阱:写了
"vendor/name": "dev-main",但minimum-stability是stable→ 报错 “Your requirements could not be resolved” - 另一个陷阱:把
minimum-stability设成alpha,但忘了有些包压根没发过 alpha 版,只打了 stable tag → 还是找不到,得看包实际发布了哪些版本 - 查包真实可用版本:运行
composer show vendor/name --all,注意输出里带(dev-)或(alpha)标记的才是对应稳定性下的有效选项
minimum-stability 看似简单,但它的影响是全局穿透的。真正难的不是写哪行配置,而是判断“这个包为什么没 stable 版”——是作者还没发版?是 repo 没配对?还是你漏看了 repositories 的必要声明?这些细节比配置本身更容易卡住人。










