composer install --no-dev 删不掉 tests/ 目录,因为该参数仅跳过 require-dev 中声明的包,不清理已安装包内部的 tests/、docs/ 等冗余路径;这些文件在 packagist 发布的 zip 包中已存在,composer 解压时原样保留。

为什么composer install --no-dev删不掉tests/目录
因为--no-dev只跳过require-dev里声明的包,不碰已安装包内部的tests/、docs/、.git/等目录。这些内容在 Packagist 发布的 ZIP 包里就存在,Composer 解压时原样保留。
常见错误现象:vendor/monolog/monolog/tests/还在、vendor/symfony/console/Resources/doc/占几 MB、du -sh vendor/* | sort -hr | head -5 显示 top 3 都是带 tests 或 Resources 的包。
-
composer show monolog/monolog查看dist字段是否存在;若为null,说明走的是 source 模式,--prefer-dist也无效 - 私有包没配
"dist"或没上传 ZIP 归档,--prefer-dist会静默 fallback 到 source,体积照涨 - 某些包(如旧版
monolog/monolog)把 Handler 示例放在tests/下,直接删目录可能引发Class not found
用archive.excludes在解压前过滤冗余路径
这是最安全的源头控制方式:告诉 Composer “下载 ZIP 后,解压时直接跳过指定路径”,不依赖人工或脚本后删。
在 composer.json 的 config 块中加:
"config": {
"archive": {
"excludes": ["/tests", "/docs", "/.git", "/benchmarks", "/examples", "/Resources/doc"]
}
}
注意:
- 路径必须以
/开头,且是 ZIP 包内相对路径(不是 vendor 下的绝对路径) - 仅对从 Packagist 下载的 dist 包生效;source 模式、path 类型仓库、未定义 dist 的私有包不支持
- 执行
composer install --prefer-dist --no-dev后,检查vendor/package-name/下是否真没了tests/
清理中文语言包的可靠做法
很多包(如 laravel/framework、symfony/translation)把 40+ 种语言全打进发布包,但线上只需 zh-CN 或 zh。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
别用 rm -rf vendor/**/lang/*[^z][^h]* 这类模糊匹配——系统 glob 支持不一,zh_TW 也可能被误删。
- 推荐用
janoside/composer-cleaner:安装后在composer.json中配置白名单"cleaner": {"whitelist": ["zh", "zh_CN", "zh_TW"]} - 若坚持脚本,用宽松匹配:
@php -r "array_map('unlink', glob('vendor/**/lang/!(zh*)', GLOB_ONLYDIR | GLOB_BRACE));",但需确认 PHP 版本 ≥ 8.1 且系统启用GLOB_BRACE - 额外路径别漏:有些包把翻译放
resources/lang/vendor/xxx(如spatie/laravel-translatable),得单独写清理命令
Docker 构建时必须分阶段且清理干净
单阶段构建里跑 composer install --no-dev --optimize-autoloader,仍可能把 vendor/bin/、.git、installed.json 全塞进最终镜像。
多阶段正确写法:
FROM php:8.3-cli-alpine AS builder
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --prefer-dist --optimize-autoloader --classmap-authoritative
RUN find vendor/ -name '.git' -prune -exec rm -rf {} + 2>/dev/null || true
<p>FROM php:8.3-cli-alpine
WORKDIR /var/www/html
COPY --from=builder /app/vendor ./vendor
COPY . .</p>
关键点:
-
COPY --from=builder /app/vendor ./vendor—— 只复制 vendor,不带tests/或.git - 不要写
COPY --from=builder /app .,否则把 builder 阶段所有残留都拖进来 - final 镜像里检查是否存在
vendor/bin/phpunit、vendor/composer/installed.json,它们都不该出现
真正容易被忽略的是:即使所有参数和脚本都配对了,只要 composer.lock 里某包的 type 是 source,或者 dist 字段缺失,--prefer-dist 就形同虚设——得先确认锁文件里每个包的安装方式,再决定要不要修 composer.json 或联系包维护者补 dist。










