生产环境禁用 composer path 仓库,因其依赖本地路径导致部署失败、lock 文件不可重现;上线前须删除 repositories 中 path 条目、改用真实版本号、生成新 lock 文件;替代方案为使用 composer-merge-plugin 构建时合并。

生产环境不能用 path 仓库,必须提前移除或替换为真实包源。 Composer 的 path 类型仓库只适用于本地开发联调,它依赖文件系统路径存在;线上服务器没有 ./modules/user 这种路径,composer install 会直接报错并中断部署,且无法自动 fallback 到远程源。
path 仓库在生产环境为什么会失败
错误现象通常是:Source directory ./modules/user does not exist 或 Could not find package myorg/user at any version。这不是网络或权限问题,而是 Composer 在解析 repositories 时发现路径不存在,就彻底放弃该仓库,也不会尝试从 Packagist 或私有源拉取同名包。
-
path仓库不参与 lock 文件的语义化版本锁定——它记录的是“软链接到本地目录”,不是版本号 - 一旦
composer.lock中包含path类型条目,该 lock 文件就丧失了跨环境可重现性 - Docker 构建、CI 流水线、新服务器初始化等场景,都默认没有开发机上的模块路径
上线前必须做的三步清理
不能等到部署时才处理。必须在代码提交前完成以下操作,否则 CI/CD 会静默失败或产生不可控行为:
- 从主项目
composer.json的repositories数组中,彻底删除所有{"type":"path",...}条目 - 将原
path引用的模块(如"myorg/user": "dev-main")改为指向真实发布的版本,例如"myorg/user": "^2.1",并确保该包已发布到私有 Packagist 或 Git Tag - 在干净环境中(无
vendor/、无旧composer.lock)运行composer update myorg/user --no-dev --lock,生成不含path的新composer.lock,然后提交
替代方案:用 composer-merge-plugin 做构建时合并
如果真需要多模块结构参与生产构建,composer-merge-plugin 是唯一可行的官方路径(注意不是 wikimedia/composer-merge-plugin),但它要求:
- 插件本身必须通过
require显式安装在主项目中,且版本兼容 Composer 2.2+ -
extra.merge-plugin.include路径必须写成相对主项目根目录的./modules/payment/composer.json,不能用../或绝对路径 - 被合并的子模块
composer.json必须是合法 JSON 对象(以{开头),不能是数组或带 BOM - 每次修改子模块配置后,必须手动执行
composer dump-autoload,install不会自动触发
真正交付生产的模块,最终都得变成带语义化版本、可独立 composer require 的包。path 仓库只是开发期的临时桥梁,桥拆掉之前,路必须先铺好。











