一个共享供应商与两个项目

One shared vendor with two projects

我现在正在处理 2 个应用程序。第一个是 CMS,第二个是商店。我想将我的供应商提升一级并在项目之间共享。

所以我的结构将是这样的:

project1/
project2/
shared_vendor/

我读到了这个。 我已将 app/autoload.php 加载程序变量从:

更改为
$loader = require __DIR__.'/../vendor/autoload.php';

至:

$loader = require __DIR__.'/../../vendor/autoload.php';

而且我也将 composer.json 中的 vendor-dir 更改为:

    "config": {
      "bin-dir": "bin",
      "vendor-dir": "vendor"
    },

至:

    "config": {
      "bin-dir": "bin",
      "vendor-dir": "/../vendor"
    },

然后我收到这个错误:

ClassNotFoundException in AppKernel.php line 20: Attempted to load 
class "CmsUserBundle" from namespace "Cms\UserBundle".
Did you forget a "use" statement for another namespace?

我做错了什么?我忘了改变什么吗? 提前致谢。

Composer 在每个项目的基础上工作。

一个项目 - 一个供应商文件夹。不是,两个项目和一个 "shared" 供应商文件夹。

我们使用 PEAR 的 "shared" 供应商文件夹方法已经很长时间了,但它根本行不通。使用全球供应商文件夹管理不同的项目需求很痛苦,因为每个项目都有不同的需求。

总之...

如果您喜欢 "shared vendor folder" 设置,我建议创建类似 "wrapper" 或 "super" 项目的东西,它充当其他两个项目的容器存储库。包装器项目将包含 composer.json 文件,其中包含两个(!)项目的要求。这意味着您在两个子项目中处理同一组依赖项。

这允许定义两个子项目(cms 和商店)的要求 在 "wrapper" 回购中。基本上,我建议采用以下结构:

|-container-project
  +-CMS
    |-src
    +-tests
  +-Shop
    |-src
    +-tests
  +-vendors      // contains dependencies for both projects (CMS + Shop)
|-composer.json  // define requirements for both projects

此设置也允许为子项目引入 composer.json 文件。 您只需将需求从超级项目的 composer.json 文件传输到子项目的 composer.json 文件。

现在,还可以通过按特定顺序注册自动加载器来调整子项目的自动加载行为。

根据您的要求,如果您 need/want 在多个项目之间共享的唯一东西是供应商目录,则您可以在每个项目中创建符号链接,除了已经具有供应商的主项目之外目录。

例如:

cd /var/www/SiteA
composer install
# git clone new project into /var/www/SiteB
cd ../SiteB
# If vendor directory is already there, delete it: rm -rf vendor
# create symlink to Site A's vendor directory
ln -s /var/www/SiteA/vendor

除非您确定所有项目都需要完全相同的依赖版本,否则这可能不是一个好的计划。

对于Laravel 5,6和7+

添加新供应商文件夹配置后:

...
"config": {
    ...,
    "vendor-dir": "../vendor"
},
...

然后运行composer update

那你需要改两个文件:

  1. 对于您的应用:public/index.php

    require __DIR__.'/../../vendor/autoload.php';

  2. 您在根文件夹中的 artisan 命令:artisan

    require __DIR__.'/../vendor/autoload.php';

  3. Illuminate\Foundation\PackageManifest中打包auto-discovery:

    $this->vendorPath = $basePath.'/../vendor'; //Change this line in constructor

再运行

php artisan package:discover --ansi

我知道这是一个老问题,但我 运行 遇到了同样的问题。我正在使用 Laravel 7,我用下面的方法解决了这个问题。
我使用以下代码在项目的根目录下编写了一个 shellscript (my-vendor.sh) :

 #!/bin/bash

MY_VENDOR_DIRECTORY=my-vendor
VENDOR_DIRECTORY=vendor

if [ ! -d "$MY_VENDOR_DIRECTORY" ]
then
  echo "Le dossier $MY_VENDOR_DIRECTORY n'existe pas : on le crée."
  mkdir "$MY_VENDOR_DIRECTORY"
else
  echo "Le dossier $MY_VENDOR_DIRECTORY existe : on le vide."
  rm -rf "$MY_VENDOR_DIRECTORY/*"
fi

echo "Copie des fichiers autoload généré depuis $VENDOR_DIRECTORY vers $MY_VENDOR_DIRECTORY."
cp "$VENDOR_DIRECTORY/autoload.php" "$MY_VENDOR_DIRECTORY"
cp -R "$VENDOR_DIRECTORY/composer" "$MY_VENDOR_DIRECTORY"

cd "$MY_VENDOR_DIRECTORY/composer"

echo "Remplacement de 'require $file' par \str_replace(\"$MY_VENDOR_DIRECTORY\/composer\/..\", \"vendor\", $file)"
sed -i "s/require $file/require \str_replace('$MY_VENDOR_DIRECTORY\/composer\/..', 'vendor', $file)/" autoload_real.php

echo "Remplacement de 'include $file' par \str_replace(\"$MY_VENDOR_DIRECTORY\/composer\/..\", \"vendor\", $file) "
sed -i "s/include $file/require \str_replace('$MY_VENDOR_DIRECTORY\/composer\/..', 'vendor', $file)/" ClassLoader.php

然后,我将 public/index.php 中的以下代码替换为:

  • require __DIR__.'/../vendor/autoload.php' => require __DIR__.'/../my-vendor/autoload.php';

之后,我在 post-autoload-dump 脚本中添加 my-vendor.sh 命令。

我在我的两个项目中进行了此修改,启动 composer dump-autoload 并且效果非常好:)

A link 要点:https://gist.github.com/flibidi67/7c2cfdc1ff1b977b48204be0bee5eb76

希望这对其他人有帮助 ;)