composer install 不创建软链接,因为它完全依赖 composer.lock,不重新解析仓库类型或触发 symlink 创建逻辑;必须用 composer update vendor/name 才能重走发现→解析→链接全流程。

为什么 composer install 不创建软链接?
因为 composer install 完全依赖 composer.lock,它不会重新解析仓库类型,也不会尝试创建符号链接。哪怕你已经配好 "type": "path" 和 "symlink": true,install 也只会复制或跳过——它不触发链接逻辑。
必须用 composer update vendor/name(推荐精确更新)才能让 Composer 重走发现 → 解析 → 创建 symlink 全流程。
- 首次引入本地包:执行
composer update my-vendor/my-package,不是install - 后续改了本地代码:不用再
update,只要 symlink 已建好,改源码即刻生效 - 如果误用了
install,vendor 里大概率是普通文件夹,得删掉再update
软链接到底有没有生效?怎么验证?
不能只看 vendor 目录存在,得确认它是符号链接本身。Linux/macOS 下运行:
ls -la vendor/my-vendor/my-package
输出中必须含 -> 才算成功;Windows 下用:
dir vendor\my-vendor\my-package
应看到 “JUNCTION” 或 “快捷方式” 字样。
还要检查 composer.lock:搜索该包名,确认 "source": { "type": "path" },而不是 "type": "git" 或缺失 source 字段。
- 没
->或没JUNCTION→ symlink 创建失败,常见于 Windows 未以管理员身份运行终端 -
composer.lock里source.type是git→ Composer 回退到了 Packagist,说明配置没匹配上(路径、name、version 三者任一错) - 链接存在但改代码不生效 → 检查是否改对了本地包目录(不是 vendor 里的副本),且没漏掉
composer dump-autoload(尤其新增类或命名空间时)
symlink 配置写在哪?主项目还是本地包?
必须写在本地包自己的 composer.json 根级,不是主项目的 repositories 里。
主项目 composer.json 的 repositories 只负责告诉 Composer “去哪找包”,而是否启用软链,由被引用包自己决定——这是 Composer ≥2.2 的行为设计。
本地包 composer.json 示例:
{
"name": "my-vendor/my-package",
"version": "dev-main",
"options": {
"symlink": true
}
}
- Windows 用户必须以管理员身份运行终端,否则
symlink静默失败并 fallback 到 copy - 旧版 Composer("symlink": true,且不报错,务必升级
- 主项目
repositories中加"options": {"symlink": true}是无效的,别白费劲
路径、包名、版本三者为什么必须严丝合缝?
Composer 对 path 仓库的匹配是“全字节比对”:大小写、短横线、斜杠、甚至空格都敏感。只要差一个字符,它就放弃本地路径,转头去 Packagist 查找,然后报 Could not find package —— 这不是网络错误,是匹配失败。
三个硬性条件缺一不可:
-
url必须是相对于主项目composer.json的路径,如"./packages/my-package",不能带末尾/,不能用../跨出项目根(Composer 会拒绝) - 本地包
composer.json中的name必须和主项目require中写的**逐字一致**,例如"acme/utils"≠"Acme/Utils" - 本地包
composer.json中的version(或 Git 分支)必须和require中写的版本号完全对应,比如写"dev-main"就得有"version": "dev-main"或已初始化 Git 并存在main分支
最容易被忽略的是:本地包目录下必须有合法 JSON 格式的 composer.json,无尾逗号、全双引号、字段完整——语法错误会导致 Composer 静默跳过该路径,连 warning 都不给。


















