composer.lock 必须提交到 git,否则跨团队依赖不一致;require-dev 依赖需严格隔离,生产环境禁用;根项目 require 应用 ^ 约束而非 *;私有包须通过 satis 等私有 packagist 统一管理。

Composer.lock 文件必须提交到 Git
不提交 composer.lock 是跨团队出现依赖不一致的最常见源头。即使所有成员都运行 composer install,只要没锁版本,composer update 在不同时间执行就会拉取不同 minor/patch 版本,尤其是当包作者发布了非语义化更新(比如在 2.1.x 中悄悄引入了 PHP 8.2 特性)时,某台机器构建失败而其他机器正常,排查成本极高。
实操建议:
-
composer.lock必须加入版本库,且禁止添加到.gitignore - CI 流程中强制使用
composer install --no-interaction --prefer-dist,禁用update - 团队需约定:只有明确需要升级依赖时,才由负责人运行
composer update vendor/package-name(而非全量 update),并同步更新 lock 文件和提交说明
require-dev 依赖要严格隔离
很多团队把测试工具(如 phpunit/phpunit、pestphp/pest)或开发工具(如 laravel/pint)放在 require-dev,却在生产环境 CI 或 Docker 构建中误执行 composer install 未加 --no-dev,导致 dev 依赖被装入生产镜像——不仅增大体积,更可能因 dev 包间接引入冲突的运行时依赖(例如 phpunit 依赖旧版 sebastian/exporter,与主项目要求的版本不兼容)。
实操建议:
- Dockerfile 中明确写
RUN composer install --no-dev --no-interaction - CI 配置里区分阶段:dev 环境跑
install,build/staging/prod 阶段一律加--no-dev - 用
composer show --dev定期审计,确认没有意外把运行时依赖错放到require-dev
约束根项目 require 版本号用 ^ 而非 *
写 "monolog/monolog": "*" 看似省事,实则等于放弃版本控制权。Composer 会始终安装最新稳定版,哪怕它已升到 v3.x(PHP 8.1+ only),而你的代码还跑在 PHP 7.4 上。更隐蔽的问题是:某些包的 * 会匹配预发布版(如 v2.9.0-rc1),触发不可预期的 break change。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
实操建议:
- 根项目
composer.json的require字段统一用^约束(如"guzzlehttp/guzzle": "^7.5"),确保只接受兼容的 patch/minor 升级 - 对强约束 PHP 版本的包(如 Laravel、Symfony),额外用
config.platform.php锁定目标环境 PHP 版本,避免本地开发和 CI 解析出不同依赖图 - 用
composer prohibits vendor/package version快速定位谁在拉取某个冲突版本
共享私有包必须用 Satis 或 private Packagist
多个团队共用内部 SDK 或组件时,若直接用 path 仓库或 vcs 指向 Git 分支(如 "type": "vcs", "url": "git@xxx:team/sdk.git"),会导致各团队各自 resolve 依赖,无法保证 SDK 所声明的 require 与下游项目兼容。尤其当 SDK 升级了 symfony/console 到 v6,而主项目仍需 v5,Composer 会静默降级或报 conflict,但错误信息常指向“无法解析 root”,掩盖真实源头。
实操建议:
- 私有包统一走 Packagist 兼容源(如 Satis、Private Packagist、JFrog Artifactory 的 Composer repo),让所有团队从同一元数据源解析依赖
- 每个 SDK 发布新版本后,必须打 Git tag(如
v2.3.1),并在 Satis 配置中启用"archive": true,生成可缓存的 zip 包,避免每次 install 都走 Git clone - 在 SDK 的
composer.json中显式声明"conflict"和"provide",比如"conflict": {"laravel/framework": ",提前拦截不兼容组合
真正棘手的依赖冲突往往不出现在 composer update 报错那一刻,而是藏在 lock 文件未提交、dev 依赖泄漏、平台配置缺失这些看似细小的选择里。盯住这四点,比事后用 composer why-not 追查两小时更有效。










