唯一可靠方式是修改项目级composer.json中的config.vendor-dir;需写在最外层config下、用相对路径、删除vendor和composer.lock后重装,且需同步更新autoload路径、bin目录及IDE配置。

想让 Composer 把包装到 third-party 或 libs 而不是默认 vendor,唯一可靠的方式是改项目级 composer.json 里的 config.vendor-dir;其他方法——比如环境变量、-d 参数、全局配置——在 Composer 2.x 中基本不生效或被静默忽略。
config.vendor-dir 是唯一真正生效的项目路径配置
这个字段必须写在项目根目录 composer.json 的最外层 config 对象里,不能塞进 extra 或缩进错位。值必须是相对路径(如 "third-party"),不能以 / 开头,也不支持 $HOME 或通配符。
- 改完后必须删掉整个
vendor目录和composer.lock,再运行composer install——update不会迁移已有包 -
autoload.php、bin/下的可执行文件、PSR-4 映射,全都会生成到新路径,但代码里所有require 'vendor/autoload.php'都得手动改成新路径,比如require 'third-party/autoload.php' - IDE(如 PHPStorm)默认只索引
vendor,需手动在 Settings → PHP → Include Paths 中添加新路径 - 如果用了
bin-dir,必须同步配:例如"bin-dir": "third-party/bin",否则phpunit这类命令链接会失效
installer-paths 只对 type 匹配的包起作用
extra.installer-paths 看起来像“按包名指定路径”,但它根本不是通用路由机制。它只在三个条件同时满足时才触发:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 目标包的
composer.json明确声明了type(如"wordpress-plugin") - 你的项目已通过
composer require composer/installers(或专用 installer 如wpackagist/installer)引入对应 installer - 你删掉了整个
vendor和composer.lock,再跑composer install—— 它不会重排已有包
普通 library 类型哪怕写进 installer-paths 规则里,也照旧进 vendor。这不是 bug,是设计逻辑:它是“installer 类型分发器”,不是“包名重定向表”。
COMPOSER_VENDOR_DIR 在 Composer 2.x 中已失效
这个环境变量曾经能控制项目级 vendor 路径,但在 Composer 2.x 中已被移除或静默忽略。你设了 COMPOSER_VENDOR_DIR="third-party",然后跑 composer install,结果还是生成 vendor/ —— 这不是你操作错,是它本来就不工作了。
-
COMPOSER_HOME仍有效,但它只管全局配置、缓存、插件位置(如~/.composer/),不影响项目依赖安装路径 -
composer install -d /path也常被误用:它只是告诉 Composer 去哪找composer.json,不改变vendor写入位置;-d /tmp/myapp≠ 把包装到/tmp/myapp/vendor,它等价于cd /tmp/myapp && composer install - 想共用一个集中
vendor?只能靠COMPOSER_HOME+ 全局config.json配vendor-dir,但这会让所有项目共享同一份依赖,不适合多项目隔离场景
最容易被忽略的一点是:改了 vendor-dir 后,bin 目录的符号链接、自动加载入口、IDE 索引、CI 脚本里的硬编码路径(如 vendor/bin/phpunit)全部要同步更新,漏掉任意一项,都可能在部署或测试时突然报错。

















