composer 从两个 composer.json 文件安装

composer install from two composer.json file

我有多个 composer.json 具有多个单独的依赖项,我想使用单个 composer install 命令在两个 composer.json 中安装所有依赖项。

位置是这样的:

| - composer.json
| - Custom
    | - Package1
        | - composer.json

第一个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
    }
}

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\": ""
        }
    }
}

我想将 Package1 内的 lavary/laravel-menu 安装到安装了所有默认包的主要供应商目录。

|- vendor  //<==want here
| - composer.json
    | - Custom
        | - Package1
            | - vendor  //<== not here
            | - composer.json

我测试过这个解决方案:

像这样:

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

这会安装软件包,但我们需要进入第二个 composer.json 而不是主 composer.json 并从第一个 composer.json.

中删除已安装的软件包

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

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

  1. 使用外部包维护依赖。

感谢 rickdenhaan 让我知道

Composer 合并插件

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

首先我们需要这个包:

composer require wikimedia/composer-merge-plugin

那么我的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
        }
    }
}

现在, 运行

composer install

 composer update

然后你在每个目录中的composer.json将被合并到默认的vendor目录中。

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

    就像 Asgardcms 所做的那样。

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

    Configuring composer.json with private bitbucket mercurial repository

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

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

这是示例解决方案:

PHP & Composer, how do I combine composer.json files

第一个解决方案适合我的情况。希望这对花费大量时间搜索的人有所帮助。