必须同时配置 "minimum-stability": "stable" 和 "prefer-stable": true,缺一不可;前者设定版本准入门槛,后者在合法候选中优先选择稳定版,单独设置 prefer-stable 无法阻止显式声明或锁文件中的非稳定版本安装。

必须同时配置 "minimum-stability": "stable" 和 "prefer-stable": true,缺一不可;只设其中一个,生产环境大概率仍会装进 beta、rc 或 dev 包。
为什么单独设 prefer-stable 不起作用
prefer-stable 本身不是开关,它只在多个候选版本都“合法”时才参与排序。如果没设 minimum-stability,Composer 默认行为是 "minimum-stability": "stable"(Composer 2.2+),但老项目或某些插件可能绕过该默认,导致实际解析出 dev-main 或 2.0.0-RC1。
-
prefer-stable: true单独存在时,不会阻止"monolog/monolog": "dev-main"这类显式声明的开发版 - 若你项目里已有
composer.lock锁着一个dev版本,composer install完全无视prefer-stable,照装不误 - 全局执行
composer config -g prefer-stable true在 Composer 2.2+ 已被移除,运行会静默失败或报错
minimum-stability 和 prefer-stable 的真实分工
minimum-stability 是门槛,prefer-stable 是排序器——前者决定“谁能进候选池”,后者决定“谁先被挑中”。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 设
"minimum-stability": "beta"+"prefer-stable": true:候选池包含1.2.0(stable)、1.3.0-RC1、1.3.0-beta2,Composer 会优先选1.2.0 - 但若
1.2.0不满足你的^1.3约束,它根本进不了候选池,哪怕再 stable 也没用 - 某个依赖包自己写了
"minimum-stability": "dev",它的子依赖就可能跳过你的全局设置,得靠"vendor/pkg": "^2.5@stable"显式卡住
改完配置后必须跑 composer update,不是 install
修改 composer.json 后,composer install 只读 composer.lock,完全不看新配置;只有 composer update(或带 --lock 的变体)才会重新走一遍依赖解析流程,把 prefer-stable 应用进去。
- 如果只想更新某一个包,用
composer update monolog/monolog,它会尊重新配置并重选版本 - 如果
vendor/里已存在旧dev包,update会尝试替换;但若锁文件里还记着"reference": "a1b2c3d",就得先删composer.lock和vendor/,再composer install重建 - CI/CD 流水线里别漏掉这步——光改配置不跑
update,上线后还是 dev 版本在跑
上线前最易忽略的残留问题
很多团队在预发环境用了 dev-develop 测试,上线时只改代码、不碰依赖,结果 composer.lock 里还锁着 "version": "dev-develop" 或带 "reference" 的 commit hash。
- 这个 hash 可能已被 force-push 覆盖,下次
composer install直接失败或拉错内容 - 上线检查清单里必须包含:
grep -A3 '"monolog/monolog"' composer.lock | grep version,确认值是"2.9.3"这类纯语义化版本,而非"dev-main" - 稳妥做法是上线前执行一次
composer require monolog/monolog:^2.9,让 Composer 主动重锁稳定版










