composer如何在离线环境中处理插件依赖?

2次阅读

离线环境需预装插件并配置本地仓库:在有网机执行composer install确保插件及依赖完整,打包插件zip,离线机通过repositories指向本地包,且php版本、composer版本、autoload均须一致。

composer如何在离线环境中处理插件依赖?

插件依赖在离线环境里根本不会自动下载

Composer 默认所有 composer installcomposer update 都会联网拉取包,包括插件(比如 hirak/prestissimophpstan/extension-installer)。离线时直接报错:Could not fetch https://repo.packagist.org/packages.json,连 metadata 都拿不到,更别说插件本身。

关键点在于:插件本质是普通 Composer 包,但它的安装时机早于主项目依赖——Composer 在解析 composer.json 阶段就尝试加载已声明的插件,此时若插件未本地存在且无法联网,流程立刻中断。

  • 必须提前在有网机器上完整安装并固化插件,不能只拷 vendor/ 目录了事
  • composer.lock 必须包含插件的精确版本、hash 和 source 类型(dist 还是 source
  • 离线机上的 Composer 版本要 ≥ 有网机的版本,否则可能不识别锁文件里的插件字段

怎么让插件不触发远程请求?

核心是切断 Composer 对 Packagist 的任何依赖。最可靠方式是用 composer install --no-plugins 跳过插件加载,但代价是插件功能全失效——这通常不可接受。真正可行的是预生成「无网络」可用的 vendor 目录:

  • 在有网环境执行 composer install --no-interaction,确保所有插件(含其自身依赖)都下载到 vendor/
  • 运行 composer archive --format=zip --dir=dist/ my-plugin 手动打包每个插件(如 phpstan/extension-installer),存为 dist/phpstan-extension-installer-1.2.3.zip
  • 在离线机的 composer.json 中,为插件添加 repositories 条目,类型设为 package,指向本地 zip 路径:
    {   "repositories": [     {       "type": "package",       "package": {         "name": "phpstan/extension-installer",         "version": "1.2.3",         "dist": {           "url": "/path/to/dist/phpstan-extension-installer-1.2.3.zip",           "type": "zip"         }       }     }   ] }

为什么 vendor/bin 下的插件二进制在离线时可能失效?

很多插件(如 php-cs-fixerphpstan)会在 vendor/bin/ 写入口脚本,这些脚本内部常硬编码 require 路径或调用 ComposerAutoloadclassLoader。离线环境下若 autoload 未正确生成,或插件依赖的其他包缺失,就会报 Class not foundrequire(): failed to open stream

  • 务必在有网机上执行 composer dump-autoload --optimize,生成优化后的 vendor/composer/autoload_classmap.php
  • 检查 vendor/bin/ 中对应脚本第一行是否为 #!/usr/bin/env php,且后续 require 的路径是相对 __DIR__ 的,而非动态拼接
  • 离线机 PHP 版本需与有网机制作环境一致,否则 opcache 或语法兼容性会导致脚本静默失败

离线部署后验证插件是否真生效?

别只看 composer install 是否成功——它可能跳过插件加载却假装完成。必须触发插件实际行为:

  • phpstan/extension-installer,运行 vendor/bin/phpstan analyse --version,输出应含 extensions installed 提示
  • hirak/prestissimo,执行 composer install -v,日志中应出现 using Prestissimo 字样,而非 Downloading...
  • 如果插件注册了 PluginInterface,可在 vendor/composer/autoload_plugins.php 中确认其类名和路径是否被正确注册

最容易被忽略的是插件自身的依赖树:比如 phpstan-extension-installer 依赖 phpstan/phpstan,后者又依赖一分析器包。这些二级依赖必须全部提前下载好,否则离线时只差一个包,整个插件就卡死。

text=ZqhQzanResources