根本原因是vendor目录中大量非运行必需的中文语言包被IDE索引,导致文件数量爆炸;删lang/可立竿见影,因其含40+语言子目录且IDE默认解析翻译键,而tests/通常被忽略。

IDE(如 PHPStorm、VS Code + PHP Intelephense)在中文环境下卡顿,根本原因不是“中文字符”本身,而是 vendor 目录里大量非运行必需的中文语言包(lang/、resources/lang/、translations/)被完整拉取并纳入索引范围——这些目录动辄几十 MB、成千上万个文件,且含大量重复结构,直接拖垮 IDE 的文件监听与符号解析。
为什么删 tests/ 不管用,但删 lang/ 能立竿见影
IDE 索引卡顿的核心诱因是文件数量而非体积。一个 laravel/framework 的 lang/ 目录包含 40+ 种语言子目录(en/、zh-CN/、ja/、fr/…),每个子目录下又有数十个 .php 或 .json 翻译文件;而 tests/ 通常只占单个包体积的 5–10%,且多数 IDE 默认忽略 vendor/**/tests/(除非你显式启用了“索引测试目录”)。但 lang/ 是合法的资源路径,IDE 会逐个解析、建立翻译键的语义索引,极易触发 CPU 尖峰和内存溢出。
-
vendor/symfony/translation自带 ICU 数据库和全部语言包,resources/下文件数超 2000 -
spatie/laravel-translatable把多语言模板放在resources/lang/vendor/spatie/,IDE 无法区分是否需索引 - 手动
rm -rf vendor/**/lang后,下次composer update全恢复,白忙活
用 post-install-cmd 自动清理非中文 lang 目录
最稳、可复现、不破坏 autoload 的方式:在 composer.json 中声明清理脚本,让 Composer 安装/更新后自动剔除非中文语言目录。它不碰 src/ 或 autoload 声明的路径,只删 IDE 索引负担重、又不影响运行的冗余资源。
- 在
"scripts"块中添加:
"post-install-cmd": [
"@php -r \"array_map('unlink', glob('vendor/**/lang/!(zh*)', GLOB_ONLYDIR | GLOB_BRACE));\""
],
"post-update-cmd": [
"@php -r \"array_map('unlink', glob('vendor/**/lang/!(zh*)', GLOB_ONLYDIR | GLOB_BRACE));\""
]
- 该命令使用 PHP
glob()匹配所有vendor/**/lang/下**不以zh开头**的子目录(覆盖zh-CN、zh-TW),然后unlink()删除 - 若系统不支持
GLOB_BRACE(如某些 Alpine Linux),改用宽松正则匹配:@php -r "foreach(glob('vendor/**/lang/*', GLOB_ONLYDIR) as $d) { if (!preg_match('/zh[-_]/i', basename($d)) && basename($d) !== 'zh') unlink($d); }" - 注意:此脚本仅清理
lang/,如需处理resources/lang/或translations/,得额外加一行(例如vendor/**/resources/lang/!(zh*))
配合 --classmap-authoritative 防止 IDE 误扫已删目录
光删 lang/ 不够。如果项目没启用 --classmap-authoritative,PHP 自动加载器仍可能在运行时 fallback 到 PSR-4 扫描逻辑,而 IDE 会同步模拟该行为——即使目录已被删,它仍尝试递归遍历 vendor/ 下所有可能路径,导致索引反复失败、重建、再失败。
- 确保
composer.json的"config"中有:"optimize-autoloader": true - 执行:
composer install --no-dev --optimize-autoloader --classmap-authoritative - 验证:
grep -c "lang/" vendor/composer/autoload_classmap.php应为 0 —— 表示 classmap 里压根没收录任何lang/下的类,IDE 不会为此建索引 - ⚠️ 开发环境慎用:启用后新增类若未被 classmap 捕获(比如刚写的命令行类没跑过
dump-autoload),会直接报错,不能 fallback
真正卡住 IDE 的从来不是“中文”,而是没被约束的文件爆炸。删 lang/ 是减量,关扫描是断源——两者缺一不可。否则哪怕只剩一个 vendor/symfony/translation,IDE 也能给你卡到弹窗提示“索引暂停”。


















