config.vendor-dir 全局修改 vendor 目录位置,需在 composer.json 最外层 config 下配置相对路径并重装;installer-paths 仅对声明 type(如 wordpress-plugin)的包生效,路径相对于项目根目录,不移动已有包。

config.vendor-dir 改的是整个 vendor 目录,不是 installer-paths
想让所有包(monolog、symfony/console 等)都装进 third-party 或 libs,只有一条路:在项目根目录 composer.json 的 config 字段里写死 vendor-dir。
必须满足三个条件才生效:
- 配置写在
composer.json最外层的config下,不能缩进错位或塞进extra - 值是相对路径,比如
"third-party"✅,"/third-party"❌,"$HOME/libs"❌ - 改完后删掉整个
vendor目录,再跑composer install——dump-autoload不管用,它不重建目录结构
改完你会发现:third-party/autoload.php 生成了,third-party/bin/phpunit 也有了,但所有 PHP 代码里的 require 'vendor/autoload.php' 得手动改成 require 'third-party/autoload.php';IDE 和 CI 脚本里硬编码的路径同理。
installer-paths 只对声明了 type 的包生效,普通库压根不走这条路
extra.installer-paths 不是“按包名搬家”,它是给 WordPress 插件、Drupal 模块这类有生态规范的包开的后门。它只在以下条件全部满足时触发:
- 目标包自己的
composer.json明确写了"type": "wordpress-plugin"(或drupal-module、typo3-cms-extension等) - 你的项目已执行
composer require composer/installers(建议版本 ≥ 2.0) - 配置写在你项目的
composer.json的extra字段下,例如:"wp-content/plugins/{$name}/": ["type:wordpress-plugin"]
{$name} 是占位符,会被替换成包名最后一段(wpackagist-plugin/akismet → akismet),路径必须以 / 结尾,且不能以 / 开头(wp-content/plugins/{$name}/ ✅,/wp-content/plugins/{$name}/ ❌)。
普通 PHP 库(type: library)哪怕你写进规则里,也照旧进 vendor/。强行给它设 type 并指望 composer/installers 处理,大概率导致 autoload 失败——PSR-4 声明的命名空间路径和实际文件位置对不上。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
installer-paths 不重排已有包,只影响新安装或更新
常见错误是:配好 installer-paths 后跑 composer update,发现插件还在 vendor/ 下。这是因为 installer-paths 不会移动已存在的包,它只在安装新包或更新匹配的包时起作用。
解决办法只有两个:
- 删掉整个
vendor目录和composer.lock,再跑composer install - 或者先卸载再重装目标包:
composer remove wpackagist-plugin/akismet && composer require wpackagist-plugin/akismet
注意:运行 composer show composer/installers 必须能看到该包已加载。如果没出现,说明它没被装进当前作用域(比如装在 require-dev 但你在生产环境跑 install --no-dev)。
config.vendor-dir 和 extra.installer-paths 别混用
两者逻辑完全不同:config.vendor-dir 是全局挪窝,所有包统一搬;extra.installer-paths 是定向劫持,只动特定 type 的包。强行叠加容易出问题。
比如你设了 "vendor-dir": "third-party",又配了 "wp-content/plugins/{$name}/": ["type:wordpress-plugin"],结果是:普通包进 third-party/,WordPress 插件进 wp-content/plugins/——这没问题;但如果你误以为 installer-paths 的路径是相对于 third-party 的,那就错了:它的路径始终是相对于项目根目录的。
另外,COMPOSER_VENDOR_DIR 环境变量在项目已声明 config.vendor-dir 时会被无视,这是优先级陷阱,CI 脚本里尤其容易踩坑。










