Managing module library dependencies with composer

I've found Dependencies in a custom module with drupal-composer, How can I include a third party library in my custom module without using Composer Manager and How to manage contrib modules composer dependencies on drupal 8 which are releated to my question, but no longer seem to apply since Drupal 8.1 and the deprecation of Composer manager.

Also popular guides such as The definitive introduction to D8 and Composer appear to no longer apply as they also mention composer manager.

The other solution opposed to composer manager, alter the core composer.json file feels like too much core hacking and would probably break with every Drush update of Drupal core(?).

More specifically, I am attempting to update Views vCards from Drupal 7 to 8. I have created my composer.json file as follows:

{
  "name": "drupal/views_vcards",
  "description": "Allows creation of vCards using the fields provided by the Views module.",
  "type": "drupal-module",
  "license": "GPL-2.0+",
  "homepage": "https://drupal.org/project/views_vcards",
  "require": {
    "maennchen/zipstream-php": "0.3.*"
  }
}

But if I put a composer.json file in my module folder, how do I make Drupal aware that that file is there, and how do I make sure the required zipstream-php library is downloaded?

Simply running composer update from the Drupal root does update a lot of Drupal dependencies, but it does not include the composer.json files that are in the modules folders. I also don't assume I should be calling composer install from inside all modules with dependencies.

How do I make Drupal aware of a module's dependency without using composer manager and/or hacking core?

UPDATE:

The composer merge plugin used by core appears to have support a wildcard path:

{
    "require": {
        "wikimedia/composer-merge-plugin": "dev-master"
    },
    "extra": {
        "merge-plugin": {
            "include": [
                "composer.local.json",
                "extensions/*/composer.json" // < ---- THIS LINE
            ],
            "require": [
                "submodule/composer.json"
            ],
            "recurse": true,
            "replace": false,
            "merge-dev": true,
            "merge-extra": false
        }
    }
}

Why doesn't core merge modules/*/composer.json, that would solve everything right?

Update 2:

THe reasoning for not supporting this is covered in this issue (which also has been quiet for some time now).

Answers 1

  • New method using drupal-scaffold for greatest flexibility

    For Drupal 8.4.0 and greater using drush >9.0.0, drush make is deprecated and you should use a full-composer work flow as detailed in the drupal.org documentation links below. Those links do recommend using a composer project, but this may not work for everyone's web server setup. The following is step-by-step how to setup composer.json manually for detail explanation. The instructions regarding adding modules manually can still be done.

    # Initialize composer. Stability alpha is important for custom modules that may be source managed outside of packagist or drupal.org
    composer init --name myvendor/mysite --stability=alpha --license=GPLv2
    composer config repositories.drupal composer https://packages.drupal.org/8
    composer config discard-changes true
    

    Then you need to add to composer.json manually the following based on your preferences because there is no way to do so automatically with composer as-is. These will configure drupal-scaffold to install your modules where you want them (as opposed to in vendor/ or a directory chosen by some other developer). Change 'webroot' to 'www' or 'public' or what your host is.

        "extra": {
            "installer-paths": {
                "webroot/core": ["type:drupal-core"],
                "webroot/modules/contrib/{$name}": ["type:drupal-module"],
                "webroot/modules/custom/{$name}": ["type:drupal-custom-module"],
                "webroot/themes/contrib/{$name}": ["type:drupal-theme"],
                "webroot/themes/custom/{$name}": ["type:drupal-custom-theme"],
                "webroot/profiles/{$name}": ["type:drupal-profile"],
                "webroot/libraries/{$name}": ["type:drupal-library"]
            },
            "patches": {}
        },
        "scripts": {
            "drupal-scaffold": "DrupalComposer\\DrupalScaffold\\Plugin::scaffold"
        }
    

    Now you can install some dependencies. Note that composer must be able to use scripts and plugins for this to work.

    composer require composer/installers:^1.4.0 drupal-composer/drupal-scaffold:^2.3.0 cweagans/composer-patches:^1.6.2
    

    Run the drupal-scaffold script once (or on your build server as needed):

    composer drupal-scaffold
    

    Drupal core, modules, themes, etc... can be installed as per the instructions below without the drupal-merge-plugin.

    composer require drupal/core:~8.5.1 drupal/views_vcards
    

    Older method using drupal-merge-plugin or working with core directly

    For Drupal 8.1.0 and greater, you can use composer to require Drupal modules directly. The documentation around Using Composer in a Drupal project and Using Composer to install Drupal packages through Drupal.org has been updated to take advantage of drupal.org's packagist. I find it works well already in a deployment scenario.

    composer config repositories.drupal composer https://packages.drupal.org/8
    composer require drupal/views_vcards
    

    For development, I think that manually adding in the dependency with composer require works fine. The merge approach works too with the drupal-merge-plugin and I use this for my drush make work flow.

    composer config repositories.drupal composer https://packages.drupal.org/8
    composer require mile23/drupal-merge-plugin
    composer update
    

    Update 2016.06.22

    I ran into an issue using drush make, which added the traditional Drupal version tags and drupal.org packagist URLs using semver. To that end, I needed to switch to using the stabler packagist at https://packagist.drupal-composer.org, which still supports the traditional Drupal version tags.

    Also note that the build server or machine requires an exorbitant amount of memory to do a composer update (or require), which is necessary in all scenarios where running composer update on a similar development machine is not possible in your build process.

    Update 2016.09.23

    Update 2018.03.30

    • Noticed an up vote. This is fairly old so decided to clarify about more recent development and setting up your site directly with composer since drush make has been (sadly) deprecated for a while.

Related Questions