composer官方认可的type值有library、project、metapackage、composer-plugin及框架专用型(如wordpress-plugin),自定义type需配套installer才生效;type仅标识包角色,不控制安装路径。

type 字段不是安装开关,改了它不会让包自动装进 wp-content/plugins 或跳过 vendor/;它只是告诉 Packagist、CI 脚本、composer/installers 等工具:“我是什么角色”。写错值或漏配配套机制,基本等于白写。
哪些 type 值是 Composer 官方认的
只有这几个字符串被官方明确定义,大小写敏感,不能拼错、不能加空格、不能自造:
-
library:默认值,不写也等价于它;适合被其他项目require的通用包,必须配autoload -
project:表示“这是个完整应用”,比如 Laravel starter;只该用于create-project场景,不该同时被require -
metapackage:纯依赖清单,不能含任何 PHP 文件(连src/都不能有),否则 Packagist 直接拒收 -
composer-plugin:必须实现Composer\Plugin\PluginInterface,且类路径要通过extra.plugin-class指定并落在autoload范围内 - 框架专用型如
wordpress-plugin、cakephp-plugin:这些不是 Composer 原生支持的,必须在require中引入composer/installers,且type值要和安装器注册的完全一致
type: project 和 type: library 实际影响在哪
表面只差一个字符串,实际触发不同协作预期和工具行为:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 设为
project:别人运行composer create-project vendor/name时会被当作模板克隆;但如果你自己项目里写了"type": "project"又出现在别人项目的require列表中,Composer 可能报循环依赖警告 - 设为
library:包会被装进vendor/author/name,自动加载按autoload配置走;这是绝大多数可复用包的正确选择 - 现象常被误判:用
create-project初始化后发现vendor/里多出一堆重复依赖,大概率是因为源项目type还是默认library,被当成普通依赖参与了解析
为什么写了 type: wordpress-plugin 却没装进 wp-content/plugins
因为 type 本身不控制安装路径,真正起作用的是 composer/installers —— 它才是那个读取 type 并决定往哪扔文件的组件:
- 必须在
require中声明"composer/installers": "^2.0"(注意版本兼容性) -
type值必须严格匹配安装器注册的名称,比如"wordpress-plugin"写成"wp-plugin"就无效 - 没有安装器时,
wordpress-plugin和library完全等价,照样进vendor/ - 如果用了
path类型本地仓库,安装器通常不生效——path是绕过常规解析流程的特例
metapackage 和 composer-plugin 容易踩的硬坑
这两类对结构和配置极其敏感,错一点就直接失败:
-
metapackage:Packagist 会扫描所有文件,只要发现src/、tests/、bin/或任意 PHP 文件,就会拒绝发布,并报错Package of type metapackage cannot contain autoloading configuration or files;必须删掉autoload、autoload-dev、bin字段 -
composer-plugin:不实现Composer\Plugin\PluginInterface,Composer 初始化时直接忽略;extra.plugin-class指定的类不在autoload范围内,运行时报Class not found;类实现了接口但没注册到autoload,也会静默失效 - 所有
type声明都必须放在composer.json根对象层级,嵌套在extra或其他字段下无效
最常被忽略的一点:你写的 type 不会影响 composer install 的执行流程,但它决定了 Packagist 是否收录、CI 是否跳过部署检查、插件系统是否加载你的类——这些链路一旦断开,问题往往出现在发布后、集成时、上线前,而不是本地 dump-autoload 那一刻。










