Composer如何添加开发环境专用依赖?(require-dev详解)

1次阅读

require-dev 中的包仅开发时安装和自动加载,生产环境(如 composer install –no-dev)完全不加载;require 中的包为运行时必需,缺失将导致类未找到错误。

Composer如何添加开发环境专用依赖?(require-dev详解)

require-dev 和 require 的区别到底在哪?require-dev 里的包只在开发时安装,上线部署(比如 composer install --no-dev)时完全不拉、不 autoload、不写进 vendor/。而 require 是运行时必需的,漏掉就直接报 class not found

  • require-dev 包不会出现在生产环境的 autoload 映射里,哪怕你手动 dump-autoload 也不行
  • require-dev 里的包可以依赖 require 里的包,但反过来不行(否则 dev 环境装不上)
  • phpunit/phpunitphpstan/phpstanlaravel/pint 这类工具几乎都该放 require-dev
  • 如果误把 monolog/monolog 这种运行时日志库放 require-dev,线上就会崩——它不参与自动加载,new MonologLogger() 直接 Fatal Error: Class 'MonologLogger' not found

怎么加一个 dev-only 依赖? 用 composer require--dev 标志就行,别手写 composer.json

composer require --dev phpstan/phpstan
  • 不加 --dev 默认进 require,这是新手最常踩的坑
  • 如果已经错装进 require,先 composer remove vendor/package-name,再重装带 --dev
  • --dev 会自动写进 require-dev 字段,并触发 composer install(除非加了 --no-install
  • 某些包(比如 symfony/var-dumper)本身是双用途的:开发时用 dump(),但某些场景也需运行时加载——这时得看它是否声明了 autoload-dev,不能光看装在哪一栏

CI/CD 或线上部署时怎么确保不装 dev 依赖? 关键是让 Composer 明白“现在不是开发环境”:

  • 部署脚本里必须用 composer install --no-dev(不是 --dev=false,后者无效)
  • 确保 COMPOSER_NO_DEV 环境变量没被意外设为 0 或空字符串——只有明确为 1true 才生效
  • Laravel 的 artisan optimize:clear 不会清理 dev-only 类的 autoloader,因为它们本来就没注册;但如果你用 composer dump-autoload --optimize 而没加 --no-dev,生成的 autoload_classmap.php 仍可能包含 dev 包的类(取决于是否用了 autoload-dev
  • docker 构建时常见错误:composer install 在构建层执行,却没加 --no-dev,导致镜像里多出几百 MB 的测试工具和文档

require-dev 会影响项目 autoload 吗? 不影响主 autoload 规则,但会影响 dev 工具自身的加载逻辑:

  • require-dev 里的包如果声明了 autoload-dev(比如 PHPUnit 的测试辅助类),这些路径只在 dev 环境下加入 autoloader
  • 主项目的 autoloadautoload-dev 是独立的:前者始终生效,后者只在 composer install 且未加 --no-dev 时才启用
  • 如果你在 tests/ 里写了 use MyPackageTestHelper;,而 TestHelper 是通过 autoload-dev 加载的,那它在线上环境根本不可用——连 class_exists() 都返回 false
  • 别指望 require-dev 能绕过 PHP 版本限制:如果某个 dev 包要求 php: ^8.2,而你的线上是 8.1,composer install --no-dev 虽然能过,但 composer update 会失败,因为 Composer 解析整个 composer.json 时仍要校验所有依赖的约束

实际项目里最容易被忽略的是:dev 依赖的版本约束会间接锁死主依赖的升级路径。比如 phpstan/phpstan v1.10 要求 phpdocumentor/Reflection-common: ^2.2,而你的主项目又依赖另一个包需要 ^3.0——这时候 composer update 就会卡住,哪怕你线上根本不用 PHPStan。

text=ZqhQzanResources