composer从两个composer.json文件安装

Pal*_*diN 3 php vendor composer-php laravel-5

我有多个composer.json具有多个单独的依赖关系,并希望composer.json使用单个composer install命令在两者中安装所有依赖项.

位置是这样的:

| - composer.json
| - Custom
    | - Package1
        | - composer.json
Run Code Online (Sandbox Code Playgroud)

第一个composer.json

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "barryvdh/laravel-debugbar": "^2.3",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "laravelcollective/html": "^5.4.0"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.7",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
        }
    },
    "autoload-dev": {
        "psr-4": {
          "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true
    }
}
Run Code Online (Sandbox Code Playgroud)

Package1目录中的第二个composer.json

{
    "name": "custom/package1",
    "description": "",
    "require": {
        "php": ">=5.6",
        "composer/installers": "~1.0",
        "lavary/laravel-menu": "1.7.1"
    },
    "autoload": {
        "psr-4": {
            "Custom\\Package1\\": ""
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想安装的lavary/laravel-menuPackage1到所有默认软件包安装在主供应商目录.

|- vendor  //<==want here
| - composer.json
    | - Custom
        | - Package1
            | - vendor  //<== not here
            | - composer.json
Run Code Online (Sandbox Code Playgroud)

我测试了这个解决方案:

/sf/answers/1941497211/

像这样:

{
    "config": {
        "vendor-dir": "../../vendor/"
    }
}
Run Code Online (Sandbox Code Playgroud)

这将安装软件包,但我们需要进入第二个composer.json而不是main composer.json,并从第一个composer.json中删除已安装的软件包.

如何在不进入单个供应商目录中的第二个或多个composer.json的情况下从主composer.json安装所有依赖项?

Pal*_*diN 7

经过一些研究和建议,我发现有多种方法可以实现这个解决方案.

  1. 使用外部包来维护依赖性.

感谢 rickdenhaan让我知道

Composer Merge插件

https://github.com/wikimedia/composer-merge-plugin

首先,我们需要这个包:

composer require wikimedia/composer-merge-plugin
Run Code Online (Sandbox Code Playgroud)

然后我的composer.json变成这样:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "barryvdh/laravel-debugbar": "^2.3",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "wikimedia/composer-merge-plugin": "^1.4"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.7",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "psr-4": {
          "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true
    },
    "extra": {
        "merge-plugin": {
            "include": [
                "Custom/*/composer.json"
            ],
            "recurse": true,
            "replace": false,
            "ignore-duplicates": true,
            "merge-dev": true,
            "merge-extra": false,
            "merge-extra-deep": false,
            "merge-scripts": true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,跑

composer install
Run Code Online (Sandbox Code Playgroud)

要么

 composer update
Run Code Online (Sandbox Code Playgroud)

然后您composer.json在每个目录中将合并到默认vendor目录中.

  1. 下一个解决方案可能是将包发布到packagist并在composer.json中需要,并且在composer安装期间将安装所有依赖项.

    就像Asgardcms所做的那样.

  2. 将私有存储库添加到composer.json.

    使用私有bitbucket mercurial存储库配置composer.json

  3. 此选项需要将metapackage的composer.json添加到主composer.json文件中.

(我不确定这个选项,但感谢JParkinson1991知道这个解决方案的人可以在这个选项上添加解释.只是为了让别人知道这个解决方案存在.)

以下是示例解决方案:

PHP和Composer,我如何组合composer.json文件

在这里,第一个解决方案适合我的情况.希望这可以帮助花费大量时间搜索的人.

  • 您尝试过作曲家路径存储库吗?https://getcomposer.org/doc/05-repositories.md#path 您提到的插件有很多报告的问题,并且不再更新。难道你的问题也不能用作曲家存储库路径来解决吗? (2认同)
  • 另请参阅 Drupal 上的此问题“停止使用 wikimedia/composer-merge-plugin”。不过,使用这个插件有很多缺点:它会带来性能损失(作曲家进程速度较慢并且下载更多元数据)和复杂性损失。建议的解决方案删除 wikimedia 合并插件并将其替换为 Composer“路径”存储库,这是一个本机 Composer 功能,可满足与合并插件相同的需求,但缺点较少。 (2认同)