Composer Installer 这个插件,名字听着像“安装 Composer 的工具”,但千万别被它骗了。它的真正使命是:让第三方包,能按你项目的框架规范,准确落到该去的地方。换句话说,你装一个 WordPress 插件,它该去 wp-content/plugins/,而不是被扔进 vendor/ 里吃灰。这事儿,全靠它来张罗。

不过,很多人兴冲冲地 composer require composer/installers 之后,发现插件根本没按预期工作。问题出在哪儿?今天就一次性把几个最容易踩的坑说清楚。
你装了插件,但包没“搬家”?先查包的 type 字段写对没
这事儿太常见了。很多人以为只要本地装了 composer/installers,所有依赖就会自动“飞”到对应目录。其实,composer/installers 只是个“搬运工”,它不负责判断包该去哪,只负责执行搬运指令。而指令的来源,是你要安装的那个包自己声明的 type。
- 一个 WordPress 插件,必须在它的
composer.json里明确写"type": "wordpress-plugin",搬运工才会把它搬到wp-content/plugins/。 - 如果它写的是
"type": "library",或者干脆没写type,那不管你怎么折腾,它都会乖乖待在vendor/里。 - 验证方法很简单:装完后,先看看
vendor/下有没有这个包。如果没有,说明它被挪走了,再去目标目录(比如wp-content/plugins/)里找找看。
所以,别指望靠改自己项目的配置去“强制”一个未声明 type 的通用库进特定目录——它根本不会触发搬运逻辑。
自定义 installer-paths 时,路径变量写法最容易出错
这个坑也高发。很多人喜欢在 installer-paths 里玩花样,比如想加个版本号什么的。但这里有个硬性限制:它只支持 {$name} 和 {$vendor} 这两个变量插值,{$version} 是不认的。
- 正确写法:
"wp-content/plugins/{$name}/": ["type:wordpress-plugin"] - 错误写法:
"wp-content/plugins/{$name}-v{$version}/": [...]—— 这种写法{$version}不会被解析,最终要么生成空目录,要么直接报错。 - 路径结尾的斜杠
/不能省,否则 Windows 下可能因为路径分隔符问题导致创建失败。 - 多个规则写在数组里,顺序不重要,但匹配优先级由
composer/installers内部实现决定,不建议靠顺序来控制逻辑。
升级到 Composer 2.5+ 后配置失效?检查 key 名拼写
Composer 2.4 起,配置项还是叫 installer-paths(拼写没变),但很多人会误写成 installers-paths 或 install-path。这类拼写错误不会报错,只会静默忽略——你配了跟没配一样。
- 必须严格使用:
"installer-paths"(注意是installer,不是installers)。 - 完整结构示例:
{ "extra": { "installer-paths": { "wp-content/plugins/{$name}/": ["type:wordpress-plugin"], "app/Modules/{$name}/": ["type:lara vel-module"] } }} - 验证是否加载成功:运行
composer config extra.installer-paths,输出应为对应 JSON 对象;若为空,说明 key 写错了,或者没放在顶层extra下。
为什么 vendor/ 里还有包残留?composer dump-autoload 不管用
另一个常见误区:以为 composer dump-autoload 能重新排列包的位置。实际上,composer/installers 是“安装时”行为,跟自动加载完全无关。它只影响 composer install 或 composer update 时的文件落点。
- 残留在
vendor/里的包,通常是因为之前没配installer-paths,包已经下载到那了。新配完后,旧包不会自动搬走。 - 解决方法:手动删掉
vendor/xxx/yyy目录,再重新执行composer install或composer update xxx/yyy。 - 另外,如果一个包既出现在
installer-paths规则里,又出现在require列表中,它仍会被复制过去——installer-paths不阻止vendor/下存在副本,只是多建一份软链接或硬拷贝(取决于实现)。
总结一下,composer/installers 的核心逻辑很简单:你配好了、包也声明了,它才会乖乖干活。否则,一切都白搭。记住这一点,后面就不会再为“为什么没生效”而抓狂了。