必须用path仓库类型显式配置本地路径并执行composer update包名,否则Composer默认按lock文件安装远程版本;本地包需含合法composer.json(含正确name、autoload)、Git已提交,且repositories块须置于主项目composer.json中require上方。

直接用 composer require 装不了本地包,必须显式告诉 Composer:「这个包不在 Packagist,去我本地磁盘找」。否则它永远只认 composer.lock 里锁定的远程版本。
本地包必须有合法的 composer.json
这是硬性前提。没有它,Composer 会报错 Could not parse version constraint 或直接跳过目录。检查点包括:
-
name字段必须存在且格式为vendor/name(如"myorg/utils"),不能是空字符串或非法字符 -
autoload建议配psr-4,例如{"MyOrg\Utils\": "src/"},否则类无法自动加载 - 目录下不能有未提交的 Git 更改(Composer 2.4+ 会拒绝 symlink 已修改的本地包)
repositories 块必须写在主项目 composer.json 顶部
位置很重要——必须放在 require 上方,否则会被忽略。路径必须是相对于主项目根目录的相对路径,不能用 ~/、/abs/path 或 Windows 盘符路径:
{
"repositories": [
{
"type": "path",
"url": "../my-local-package"
}
],
"require": {
"myorg/utils": "dev-main"
}
}
注意:"dev-main" 是分支名,不是版本号;如果本地包用的是 main 以外的分支(比如 develop),这里要同步改成 "dev-develop"。
执行 composer update 时必须指定包名
运行 composer update myorg/utils,而不是 composer update 全量更新。原因:
- 全量更新可能误触其他依赖,导致
composer.lock意外变更 - 不带包名时,Composer 可能忽略
path仓库配置,回退到 Packagist 查找 - 成功后
vendor/myorg/utils会变成符号链接,指向你指定的../my-local-package
为什么 composer link 容易出问题?
它只适用于「已安装过的包」,且不改 composer.lock,后续 composer update 极大概率把它打回原形。典型翻车场景:
- 先
composer require myorg/utils装了个远程版,再进本地包目录执行composer link,最后回主项目composer link myorg/utils - 下次有人
composer install,因为composer.lock还锁着远程版本,链接直接消失 - autoload 也不会自动重生成,常出现
Class not found
真正需要快速验证时,宁可删掉 vendor/myorg/utils 和 composer.lock 里对应条目,再走一遍 path + update 流程——慢半秒,但稳得多。


















