composer show -s 显示各包在 vendor 中的源码目录实际磁盘占用,含测试/文档等非运行必需文件,按字母序排列而非体积大小,需配合 du 等工具排序分析。

composer show -s 显示每个包的磁盘占用
Composer 本身不直接提供“包体积分析”功能,但 composer show -s 是最接近的内置命令——它会列出所有已安装包及其源码目录大小(即 vendor/{vendor}/{package} 下的实际磁盘占用)。这个值反映的是解压后、含测试/文档等非运行必需文件的完整体积。
常见错误现象:composer show 不加 -s 时完全不显示大小;有人误以为 composer outdated 或 composer depends 能查体积,其实不能。
-
composer show -s只统计当前vendor/下真实存在的目录,不会估算下载包体积或压缩包大小 - 结果按字母序排列,不是按大小排序,需配合
grep或重定向到文件后手动处理 - 某些包(如含大量二进制资源的
laravel/horizon)可能单个占几十 MB,但-s输出里只是普通数字,需肉眼识别“大块头”
用 du + composer show 手动排序找最大包
想快速定位前 5 大包?composer show -s 输出不易排序,更可靠的做法是直接扫 vendor/ 目录。Linux/macOS 下一行就能搞定:
du -sh vendor/* 2>/dev/null | sort -hr | head -5
这比依赖 Composer 命令更准:跳过符号链接干扰,包含所有子目录(比如 vendor/foo/bar/res/ 里的大图片),且单位清晰(M/G 自动识别)。
- Windows 用户可用
Get-ChildItem vendor | Sort-Object Length -Descending | Select-Object Name,Length -First 5(PowerShell),注意Length是字节数,需手动换算 - 别漏掉
2>/dev/null:避免因权限问题或损坏包中断输出 - 某些包(如
symfony/symfony全量安装)会把组件全塞进一个目录,du能真实暴露它吃掉的空间,而composer show -s可能只显示主包名,掩盖内部膨胀
为什么 vendor 里有些包特别大?常见原因和检查点
不是所有“大包”都该删——得先判断它大得有没有道理。典型情况有三类:
- 带前端资源:如
twbs/bootstrap的dist/和scss/全在 vendor 里,实际运行只需dist/css,其余可被构建工具忽略 - 含测试/fixture 数据:如
phpunit/phpunit自带大量 XML/JSON 测试用例,生产环境完全用不到 - 历史遗留臃肿包:比如旧版
monolog/monolog曾打包了全部 Handler 示例代码,新版已精简;此时升级比手动删文件更安全
检查方法:进对应 vendor/{vendor}/{package} 目录,用 du -sh * 看哪一层占空间最多。别急着 rm -rf tests/——有些包的自动加载逻辑依赖这些路径存在。
composer-unused 或 proget 检测“无用但占空间”的包
真正该警惕的不是“大”,而是“大且没被引用”。比如你装了 guzzlehttp/guzzle,但代码里从没 use GuzzleHttp\ 或调用 new Client(),它就纯属冗余。
composer-unused 这类工具能扫描 src/ 和 tests/ 下所有 PHP 文件,对比 composer.json 的 require 列表,标出未使用的包。但它不分析体积,只管“是否被引用”。
- 安装:
composer global require composer-unused/composer-unused - 运行:
composer-unused --no-dev(排除 dev-only 包) - 注意:它无法识别动态加载(
class_exists('Foo') + new $class)、配置驱动加载(如 Laravel Service Provider)、或注解扫描(如 Doctrine ORM),这些场景会误报“未使用”
复杂点在于:一个包可能体积不大但被深度依赖,另一个体积巨大却只被一行 require_once 调用——删哪个,得看代码上下文,不能光看数字。










