
生产环境不能靠 minimum-stability 设为 stable 就高枕无忧——它拦不住显式写的 dev-main,也管不了子依赖自己设的 minimum-stability: dev。真正起效的是组合策略:全局门槛 + 显式约束 + CI 硬检查。
为什么 minimum-stability: stable 还会装上 dev-main
因为 minimum-stability 是“最低准入线”,不是“最高限制”。它只对没写明稳定性的约束起作用,比如 "monolog/monolog": "^3.0";一旦你在 require 里写了 "monolog/monolog": "dev-main" 或 "monolog/monolog": "^3.0@dev",Composer 就直接绕过门槛,照单全收。
更隐蔽的是传递依赖:你依赖的 A 包,在它自己的 composer.json 里写了 "minimum-stability": "dev",那它的子依赖 B 就可能被拉成 dev-main,哪怕你项目里设了 stable。
minimum-stability 必须放在 composer.json 根对象层级(和 require 同级),写在 config 或 extra 里完全无效改完后必须运行 composer update –lock,否则 composer.lock 仍锁着旧规则下的版本dev-main 不是语义化版本,每次 composer update 都可能拉新 commit,不适合生产环境
如何安全安装单个 dev 分支(不污染整个项目)
别动全局 minimum-stability。临时装一个开发分支,最可控的方式是用命令行参数精准授权:
composer require vendor/package:dev-main –stability=dev
这个参数会覆盖 composer.json 中的设置,仅对当前命令生效。关键点在于:必须同时指定分支名(如 dev-main)和 –stability=dev,缺一不可。
如果包来自私有 Git 仓库,确保已配置 repositories,类型为 vcs执行后,composer.lock 会记录具体 commit hash,而非分支名——下次 composer install 锁定该 commit,不会自动更新若只想试用,不写进 composer.json,可用 composer require –no-update vendor/package:dev-main –stability=dev,再手动 composer update
CI 流程中彻底拦截 dev 版本的硬手段
靠人肉 review composer.json 或凭经验判断太不可靠。CI 中必须加一行脚本做最终兜底:
grep -q ‘"version":"dev-‘ composer.lock && exit 1
这行命令会在构建时扫描 composer.lock,只要发现任何 "version":"dev- 字样就立即失败。它不依赖配置是否正确,只认最终锁定结果。
比 composer show -a 更真实:后者只查 Packagist 索引,而 composer.lock 是实际安装依据能捕获被传递依赖悄悄带进来的 dev-main,哪怕你 require 里一个 @dev 都没写配合 composer validate 和 composer install –no-dev –no-scripts 使用,构成完整防线
prefer-stable: true 的真实作用和常见误用
prefer-stable 不改变“能不能装”,只影响“在合法范围内选哪个”。它只有和 minimum-stability 配合才有意义。
例如:"minimum-stability": "beta" + "prefer-stable": true → 当 monolog/monolog 同时有 3.5.0 (stable) 和 4.0.0-beta2 (beta) 满足 ^4.0 约束时,选前者;但若只有 4.0.0-RC1,它照装不误(因 RC ≥ beta)。
单独设 "prefer-stable": true 基本无效——默认 minimum-stability 就是 stable,池子里本来就没别的CI 和本地开发环境必须保持一致:本地开了 prefer-stable,CI 没开,可能导致部署时类找不到(beta 版重构了命名空间)想让 dev-main 生效?得把 prefer-stable 设为 false,否则它会优先找 stable 版,哪怕你明确写了 dev-main
最容易被忽略的是:稳定性等级是单向过滤的,dev ,且 <code>RC 不等于 stable。哪怕一个包只差一次发布动作,minimum-stability: stable 就会把它拒之门外——这不是 bug,是设计使然。

评论(0)