composer如何使用path-repository软链接_composer symlink模式开发【联动】

8次阅读

path-repository不能用相对路径因解析基于项目根目录而非composer.json位置,须用绝对路径或./开头的根相对路径;联动开发需确保path包含.git、主项目启用dev稳定性、version设为dev-main等。

composer如何使用path-repository软链接_composer symlink模式开发【联动】

path-repository 为什么不能直接写相对路径

因为 composer.json 中的 path 类型仓库路径,是相对于当前项目根目录解析的,不是相对于 composer.json 文件位置。如果你在子目录里执行 composer install,或者用 CI 工具切换工作目录,相对路径会失效——它压根不支持 ../my-package 这种写法,一写就报 Source path ".../my-package" does not exist

实操建议:

  • 所有 path 值必须是绝对路径,或以 ./ 开头的、从项目根出发的路径(如 ./packages/my-package
  • 避免跨 Git 仓库软链接:Composer 不会自动跟踪 symlink 目标是否已提交或更新,容易出现本地有改动但 composer update 没感知
  • 如果包本身有 autoload 配置,确保它的 psr-4 映射路径与实际文件结构一致,否则类找不到

如何让 path-repository 真正“联动”开发

所谓联动,是指改了本地包代码,主项目立刻生效,不用反复 composer update。这依赖 Composer 的“符号链接安装”行为,但默认只在满足条件时触发。

实操建议:

  • 主项目的 composer.json 必须启用 prefer-stable: falseminimum-stability: "dev",否则 Composer 会跳过本地 path 包,去拉 dist 包
  • path 包的 composer.jsonversion 字段要设为 dev-maindev-develop,不能是 1.0.0 这类稳定版号,否则会被当成已发布版本忽略
  • 运行 composer require vendor/name:dev-main --no-update 后再 composer update vendor/name,强制走 symlink 而非 copy
  • 验证是否成功:检查 vendor/vendor/name 是否是 symlink(linux/macos)或 junction(windows),而不是复制出来的文件夹

常见错误:require 后没生成 symlink,还是 copy 了一份

现象是改了 path 包里的代码,主项目 var_dump 却没变;ls -l vendor/xxx 显示是普通目录,不是链接。根本原因是 Composer 认为这个包“可安装为 dist”,于是跳过了 symlink 逻辑。

排查和修复步骤:

  • 运行 composer show vendor/name,看输出里有没有 source: path /xxx/yyy —— 如果显示 dist: 且带 zip url,说明没走 path 模式
  • 检查 path 包根目录下是否有 .git 文件夹:没有的话,Composer 默认 fallback 到 dist 安装;加一个空 .git 目录(哪怕没 commit)就能强制走 source 模式
  • 确认主项目 config 段没设置 "preferred-install": {"*": "dist"},这个配置会全局压制 symlink
  • 删掉 vendorcomposer.lock,重新 composer install

Windows 下 junction 替代 symlink 的兼容性注意点

Windows 默认不支持 mklink 创建 symlink(需要管理员权限或开启开发者模式),Composer 会退而求其次建 junction,但它有硬限制:目标路径不能跨盘符,也不能指向网络路径。

实操建议:

  • 把主项目和 path 包放在同一磁盘(比如都在 C:work 下),否则 junction 创建失败,Composer 会静默回退到 copy
  • 如果遇到 Could not create junction 错误,先手动用管理员权限运行:mklink /j C:pathtovendorvendorname C:pathtoyourpackage,再跑 composer install
  • PHP realpath() 在 junction 下可能返回原始路径而非链接路径,调试时别全信 __DIR__ 输出,用 readlink()(Linux/macOS)或 fsutil reparsepoint query(Windows)确认真实指向

事情说清了就结束。最常卡住的地方其实是 path 包缺 .git 目录,以及主项目 lock 文件里残留了旧的 dist 引用——这两处一错,联动就断了,而且错误不报在表面。

text=ZqhQzanResources