repositories 必须是数组,不能写成对象;url 必须为含 composer.json 的相对路径目录;name 和 version 需与 require 严格一致;path 源修改后需检查 symlink 是否降级为 copy;composer.json 缺失或错误会导致源被静默忽略。

repositories 必须是数组,不能写成对象
Composer 会静默忽略 repositories 字段为对象(比如 {"type": "path", "url": "./pkg"})的配置。它只认数组格式,哪怕只配一个本地源,也得包在 [{}] 里:"repositories": [{"type": "path", "url": "./packages/my-utils"}]。写成对象不会报错,但后续 composer install 或 composer require 完全看不到这个源。
url 必须指向含 composer.json 的目录,且只能用相对路径
url 不是文件路径,也不是 file:// 链接,更不是绝对路径。它必须是从当前项目 composer.json 所在位置出发、能抵达本地包根目录的相对路径,且该目录下必须存在合法的 composer.json:
- ✅ 正确:
"../my-pkg"、"./packages/api-client"(以./或../开头) - ❌ 错误:
"/home/user/my-pkg"、"C:\my-pkg"、"~/my-pkg"、"my-pkg"(缺上级路径)、"../my-pkg/composer.json"(指向文件而非目录)
Windows 下还要避开中文路径、OneDrive 同步文件夹、NTFS 权限限制——这些都可能导致 Composer 读不到 composer.json 内容而跳过该源。
本地包的 name 和 version 必须与 require 严格对齐
Composer 不看目录名,不猜包名,只比对本地包 composer.json 里的 name 字段和主项目 require 中写的字符串。二者必须逐字一致(大小写、斜杠、连字符全敏感):
- 本地包
composer.json写的是"name": "acme/api-client",主项目就得写"acme/api-client": "dev-main" - 若本地包没打 tag,就用分支名作版本约束,如
"dev-main"(先运行git branch --show-current确认) - 别写
"*"或"^1.0"—— 这些会绕过path源,退回到 Packagist 查找 - 本地包若未初始化 Git,需手动加
"version": "dev-main",否则 Composer 推不出版本
修改本地包代码后主项目没生效?检查 symlink 是否 fallback 到 copy
Composer 默认对 path 类型仓库尝试创建符号链接(symlink),但 Windows 下常因权限或策略限制自动降级为复制(copy)模式。此时改本地包代码,vendor/ 下的副本不会更新:
- 确认是否启用了 symlink:查看
vendor/acme/api-client是个快捷方式(Windows)还是普通文件夹 - 若为 copy 模式,可临时在本地包
composer.json加"options": {"symlink": true},再运行composer update acme/api-client - 注意:symlink 仅在
composer update时生效,install不重建链接
最易被忽略的是:所有配置都写对了,但本地包目录里压根没有 composer.json,或者它语法错误、缺 name 字段——Composer 就当它不存在,连 warning 都不给。











