Composer Managed Custom WordPress & Drupal Dependencies

In web development we often find ourselves writing custom WordPress plugins, Drupal modules, or themes that have external package dependencies. It’s standard to use Composer for Drupal and WordPress package management. So often we find projects that require their custom code dependency in the root composer.json file of the project. Though quick, that solution is not great because it doesn’t maintain the relationship to the dependee directly. Over time the details behind the requirement will be lost.

In an ideal world, each custom plugin or module should be responsible for defining its own dependency packages. When the dependency is clearly related to the custom code the work becomes more reusable. It can easily be moved between projects because its dependencies are clear.

An additional benefit of this ideal scenario arises when multiple plugins or modules require the same package. When this happens the dependency versions are allowed to resolve themselves through the normal composer process. No more having multiple versions of a package installed, each racing to be loaded first.

Enter the Composer Merge Plugin

Luckily, our ideal scenario can be achieved with the Composer Merge Plugin by Wikimedia. This composer plugin allows us to “merge” nested composer files throughout our project so that a single command of composer install can install and autoload the dependencies for all our custom code.

The first thing we need to do is require the composer-merge-plugin in our project’s root composer file.

composer require wikimedia/composer-merge-plugin

The composer-merge-plugin allows us to define a new section named merge-plugin in our root composer.json‘s extra: {} object. In addition to defining which other JSON files should be merged into our root file, we can use wildcards to define the path to those JSON files.

The following are examples of how we can use this plugin in both WordPress and Drupal sites to manage the dependencies of our custom code.

Composer to manage WordPress Custom Plugin & Theme Dependencies

This example shows how to use the composer-merge-plugin to manage the dependencies for your custom WordPress plugins and themes.

{
  "name": "daggerhartlab/my-wordpress-project",
  "type": "project",
  "require": {
    "wikimedia/composer-merge-plugin": "^2.0"
  },
  "config": {
    "allow-plugins": {
      "wikimedia/composer-merge-plugin": true
    }
  },
  "extra": {
    "merge-plugin": {
      "include": [
        "wp-content/plugins/*/composer.json",
        "wp-content/themes/*/composer.json"
      ]
    }
  }
}

Notes:

  • The use of the wildcard may not be desired for WordPress plugins, as some contributed plugins come with their own composer.json file. I’ve not tested how this works out in this scenario, ymmv.
  • Instead, it may be worthwhile just to include the path to specific custom plugin’s composer.json files you want to manage at the root level.

Composer to manage Drupal Custom Module & Theme Dependencies

This example shows how to use the composer-merge-plugin to manage the dependencies for your custom Drupal modules and themes.

{
  "name": "daggerhartlab/my-drupal-project",
  "type": "project",
  "require": {
    "wikimedia/composer-merge-plugin": "^2.0"
  },
  "config": {
    "allow-plugins": {
      "wikimedia/composer-merge-plugin": true
    }
  },
  "extra": {
    "merge-plugin": {
      "include": [
        "web/modules/custom/*/composer.json",
        "web/modules/custom/*/modules/*/composer.json",
        "web/themes/custom/*/composer.json"
      ]
    }
  }
}

Notes:

  • Since it is conventional in Drupal projects to separate out custom modules and themes into the modules/custom and themes/custom folders, we can reliably ensure that we are only merging composer.json files from our custom code.
  • It is also conventional that Drupal modules can include sub-modules, so we have an extra line here that will attempt to detect composer.json files within each custom module’s modules folder.

Takeaways

After updating the root composer.json file to match these examples, you can now include the dependencies for the custom plugin/module in their own composer.json file.

Running composer install should pull in the dependencies for your custom code and place it within the vendor folder alongside other project dependencies. If you have trouble with this, try running composer update --lock before composer install

If you’d like to know more about composer, check out our article on how to include Git repos with composer.

0 Thoughts

Discussion

Leave a Reply

Your email address will not be published. Required fields are marked *