installed.json 是 Composer 执行 install 或 update 时必须写入的运行时元数据快照,记录 vendor/ 中各包的名称、版本、源类型、路径、自动加载配置等真实安装状态,不可删除或手动修改。

installed.json 是 Composer 安装过程的必然产物
这个文件不是“额外生成”的,而是 Composer 执行 composer install 或 composer update 时,**必须写入的运行时元数据快照**。它记录了当前 vendor/ 目录下每个已安装包的精确状态:名称、版本、源类型(dist / source)、安装路径、自动加载配置、依赖关系等。没有它,Composer 就无法可靠判断哪些包已安装、是否需要重装、能否安全执行 composer dump-autoload 或 composer show。
它和 composer.lock 的分工很明确
composer.lock 是你提交到 Git 的“声明式契约”——它锁定的是你**期望安装什么**;而 vendor/composer/installed.json 是实际执行后的“事实性快照”——它反映的是你**此刻真正装了什么**。两者不等价:
-
composer.lock可能包含未安装的包(比如你删了vendor/但没删 lock 文件) -
installed.json只有在vendor/存在且完整时才有意义,且每次安装/更新都会被覆盖重写 - 如果你手动修改
installed.json,Composer 下次运行会直接无视并重建——它不接受人工编辑
为什么不能删掉或忽略它?
很多工具链依赖这个文件做快速元数据读取,而不是反复解析 composer.json 或扫描整个 vendor/ 目录:
-
composer show命令直接读它,响应极快 - 某些插件(如
composer-unused)用它分析实际使用了哪些包 - 部署脚本若跳过
composer install而直接 rsyncvendor/,这个文件就是验证安装完整性的第一道依据 - PHP 自动加载器(
vendor/autoload.php)初始化时也会检查它是否存在且可读
删除它会导致 composer install 重新触发全量扫描,显著拖慢后续命令;更严重的是,部分依赖运行时读取它的工具会直接报错,例如出现类似 file_get_contents(vendor/composer/installed.json): failed to open stream 的错误。
它和 autoload_static.php 有什么关系?
两者都位于 vendor/composer/ 下,但职责不同:autoload_static.php 是优化后的类映射缓存(由 composer dump-autoload --optimize 生成),而 installed.json 是包级元数据。前者可选、可重建;后者是强制存在、不可跳过的基础设施文件。即使你禁用所有 autoloader 优化,只要用了 Composer 管理依赖,installed.json 就一定存在。
{
"packages": [
{
"name": "monolog/monolog",
"version": "3.5.0",
"version_normalized": "3.5.0.0",
"type": "library",
"autoload": { "psr-4": { "Monolog\\": "src/" } },
"dist": { "type": "zip", "url": "https://api.github.com/repos/Seldaek/monolog/zipball/..." }
}
]
}
这个结构里没有魔法,只有 Composer 运行时写入的真实状态。别把它当配置文件,也别试图 diff 它——它只服务当下环境,且随时可能被覆盖。










