根本原因是Vagrant共享文件系统(如vboxsf)对大量小文件I/O低效,导致Composer依赖解析、插件扫描、autoload生成等操作频繁触发stat/openat调用而卡顿;需禁用platform-check、强制prefer-dist、显式声明插件、清除缓存、避免symlink跨宿主路径,并卸载fxp/composer-asset-plugin。

为什么 composer install 在 Vagrant 中卡在 Resolving dependencies
根本原因不是网络慢,而是 Composer 默认启用的 platform-check 和 git clone 策略在虚拟机里频繁触发文件系统同步与权限检查。Vagrant 的 shared folder(尤其是 VirtualBox 的 vboxsf)对大量小文件读写极其低效,而 Composer 解析依赖时会反复 stat 数千个 composer.json 和 composer.lock 文件。
- 禁用平台检查:
composer install --no-platform-check,跳过 PHP 扩展/版本校验(开发环境通常安全) - 强制使用 dist 包:
composer config --global prefer-stable true+composer config --global prefer-dist true,避免 git clone 源码 - 关闭插件自动加载:
composer config --global disable-tls false不是重点,真正有效的是composer config --global store-auths false避免每次读取 ~/.composer/auth.json
如何让 composer update 不再反复扫描 vendor 目录
Composer 2.x 默认启用 plugin-api-version 自动发现,但 Vagrant 共享目录下 vendor/composer/installed.json 时间戳易失真,导致它误判需重载插件并递归扫描整个 vendor。这不是 bug,是设计上对 NFS/vboxsf 的不友好。
- 在项目根目录创建
composer.json并显式锁定插件:{ "config": { "allow-plugins": { "phpstan/phpstan-nette": true, "dealerdirect/phpcodesniffer-composer-installer": true } } } - 运行前清空缓存:
composer clear-cache,否则旧缓存中残留的 symlink 路径会引发重复解析 - 避免在共享目录中执行
composer update—— 把vendor移到本地路径(如/home/vagrant/vendor),再用COMPOSER_VENDOR_DIR=/home/vagrant/vendor composer install
替换默认仓库源后仍慢?检查是否被 fxp/composer-asset-plugin 拖垮
这个已废弃的插件(常见于老 Yii2 项目)会在每次操作中调用 Bower/NPM API,而 Vagrant 内 DNS 解析和 TLS 握手在 VirtualBox 下延迟极高。即使你换了 packagist.phpcomposer.com,它仍会直连 github.com 获取 asset 包元数据。
- 卸载插件:
composer global remove fxp/composer-asset-plugin(全局)或项目内composer remove fxp/composer-asset-plugin - 改用官方方案:Yii2 项目应切换至
npm-asset-packagist.org,并在composer.json中配置:"repositories": [ { "type": "composer", "url": "https://asset-packagist.org" } ] - 确认无残留:运行
composer show --plugins,输出里不应出现fxp相关条目
composer dump-autoload 卡住不动?大概率是 autoloader 生成时遍历了错误路径
Composer 默认扫描 vendor/autoload.php 引用的所有目录,但如果项目用了 symbolic link 指向宿主机路径(比如 ln -s /host/project/src src),Vagrant 会把 symlink 当作真实目录递归进去,瞬间触发数万次 I/O。
- 用
--optimize强制生成静态映射:composer dump-autoload --optimize --classmap-authoritative - 排除无关目录:在
composer.json的autoload段明确指定路径,不要用"psr-4": {"": "src/"}这种宽泛写法 - 检查 symlink 状态:
ls -la src,若指向/vagrant/...或/host/...,立刻改为复制或绑定挂载,别让 Composer 看见跨文件系统链接
最麻烦的不是哪条命令慢,而是多个机制叠加 —— 比如 prefer-dist 关了但插件还在拉 git,--no-platform-check 加了但 symlink 让 dump-autoload 又卡住。得一层层剥开看 strace -e trace=openat,stat,read composer install -vvv 输出里到底在反复读哪个路径。










