Composer轻量化的本质是主动裁剪require和require-dev,而非依赖自动开关;create-project仅复制并安装composer.json中的依赖,不判断实际需求,需手动精简、替换重型包、优化autoload映射。

composer 本身不构建项目,它只管理依赖;所谓“轻量级”,本质是你对 require 和 require-dev 的主动裁剪,而非靠某个开关自动变轻。
为什么 composer create-project 默认不轻量
新建项目时,很多人直接运行:
composer create-project laravel/laravel myapp
结果发现 vendor/ 超过 100MB,启动慢、部署卡、CI 耗时长。这不是 composer 的错,而是 Laravel 框架默认拉取了全套组件(如队列驱动、缓存适配器、邮件传输器、完整测试工具链),哪怕你只写一个 index.php。
关键点在于:create-project 只是把目标项目的 composer.json 复制过来并安装,它不判断你是否真需要这些包。
- 它不会跳过
symfony/console,哪怕你没写任何命令 - 它不会忽略
phpunit/phpunit,哪怕你从不跑测试 - 它照单全收
monolog/monolog、guzzlehttp/guzzle等间接依赖,只要上游声明了就装
如何手动精简 composer.json 的 require 区域
不要依赖框架脚手架生成的“开箱即用”配置。从最小可行集开始,逐步加。
- 删掉所有带
-dev后缀的包(如phpunit/phpunit、laravel/pint),除非你明确要本地开发时用 - 移除未被代码直接引用的包:运行
composer show --tree查看依赖树,再用grep -r "use.*Class" .或 IDE 的“Find Usages”确认是否真用到了某类 - 替换重型包为轻量替代:
- 不用
guzzlehttp/guzzle→ 改用原生cURL或ext-http(如果已启用) - 不用
monolog/monolog→ 直接error_log()+file_put_contents()写简单日志 - 不用
symfony/console→ 用argv+getopt()手写 CLI 入口
- 不用
示例:一个仅需 HTTP 响应和路由的微服务,composer.json 的 require 可以只留:
"require": {
"php": "^8.2",
"nyholm/psr7": "^1.8",
"guzzlehttp/psr7": "^2.6"
}注意:这里没写 slim/slim 或 league/route,因为它们不是必须——你可以自己用 $_SERVER['REQUEST_URI'] + switch 分发。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
composer install --no-dev --optimize-autoloader 不是银弹
这条命令常被当作“轻量化秘诀”,但它只解决表层问题:
-
--no-dev确实跳过require-dev,但不会删掉require里本就不该存在的包 -
--optimize-autoloader只加速类加载,对vendor/体积无影响 - 如果你
require了doctrine/orm却只用PDO,优化后依然白占 30MB
更危险的是:某些包(如 ramsey/uuid)在 require-dev 里声明了测试用的 phpspec/phpspec,但它的主逻辑又依赖 ext-mbstring —— 你删掉 phpspec 没用,真正该做的是确认是否真的需要 UUID v4,还是用 bin2hex(random_bytes(16)) 就够了。
容易被忽略的隐性重量:autoload 与 PSR-4 映射
一个常被忽视的膨胀源是 autoload 配置。比如你写了:
"autoload": {
"psr-4": {
"App\": "src/"
}
}但 src/ 下混着 src/Commands/(你根本不用 CLI)、src/Events/(你没实现事件总线)、src/Http/Controllers/(你只用函数式路由)——这些目录虽不增加下载体积,却会让 composer dump-autoload -o 生成巨大的 vendor/composer/autoload_psr4.php,拖慢每次请求的 autoloader 初始化。
建议:
- 只映射你真实用到的命名空间子目录,如
"AppHttp": "src/Http/" - 避免用通配符或宽泛前缀(如
"App")覆盖整个src/ - 若项目极小(files 加载关键文件:
"autoload": { "files": ["src/helpers.php", "src/bootstrap.php"] }
真正的轻量,始于克制地声明依赖,而不是事后压缩。

















