Composer illustration

Composer for Drupal

This is the presentation I would have loved to see when I started using Composer with Drupal. This article is based on my experience working with the Dependency Management for PHP: Composer together with Drupal (version 7and 8).

Composer is the dependency manager for PHP. You can use it to declare the libraries of your project and Composer will manage (install/update) them for you. The arrival of Drupal 8 and the fact that it would use Composer as the default dependency manager made things easier. Before version 8, working with Composer in Drupal 7 was more complicated.

Why using Composer?

Never miss a dependency again: Composer will make sure all your dependencies are well organised and in the exact expected version. Having the exact version is really useful when you work with a team.

Clear view on your project’s requirements: Composer is based on JSON files. They are easy to read. Also Composer comes with useful commands that can help you manage and organise your dependencies.

Smaller amount of data in your git repo: Instead of having all your dependencies inside git, you will only have the JSON files of composer for your dependencies.

Makes maintenance easier: One command line and all your modules can be updated. How good is that? Also I am a huge fan of using code reviews, and in general the practice of submitting code for reviews. Composer really helps tracking potential hacks on dependencies! It makes code reviewing faster and more efficient.

Composer commands

$ composer install Creates a vendor folder and downloads all dependencies.

$ composer update Updates the dependencies according to composer.json.

$ composer require Adds a new dependency.

$ composer remove Removes a dependency.

Debugging? $ composer install -vvv Verbose mode will let you see what is composer doing.

Composer files

Simply remember:

  • composer.json: list of dependencies for the project.
  • composer.lock: expected install state.

composer.json

To include the latest version of Drupal 8 core as a dependency to your project, in your composer.json, you would have something like:  "require": {   "drupal/core": "~8.0",   ...

Composer.json uses versions. In our example, drupal/core": "~8.0", ~8.0 is equivalent to >=8.0 <9.0. The ~ will keep our version as Drupal 8.

composer.lock

The file composer.lock contains all informations about your dependencies, including which exact version is in use.

"name": "drupal/core", "version": "8.1.10", "source": {  "type": "git",  "url": "https://github.com/drupal-composer/drupal-core.git",  "reference": "9562f733cdefd735337bf827b3ba5ad031aba4c3" },

In GIT, commit composer.json and composer.lock. Do not commit the vendor folder in GIT. It would defeat the purpose of using composer to manage your dependencies.

Composer for Drupal

Use the composer template for Drupal projects: https://github.com/drupal-composer/drupal-project

Quick installation via: $ composer create-project drupal-composer/drupal-project

Using the template for Drupal projects, files used by Drupal (such as modules) will be placed at the right location.

Core > web/core Contrib modules > web/modules/contrib Contrib modules > web/themes/contrib

Need a new module? Example with Pathauto: $ composer require drupal/pathauto Then enable the Pathauto module.

Update all dependencies. $ composer update

Updating all dependencies is slow, instead you should update a specific module, and its own dependencies: $ composer update drupal/panels --with-dependencies

Update Drupal core. $ composer update drupal/core --with-dependencies

Patches? Use composer-patches: https://github.com/cweagans/composer-patches You only have to declare the patch in your composer.json with the module's version, and a URL to the patch to be applied.

Composer's performance

This is the sad part. Composer is super useful, but not perfect: it's pretty slow. Composer will check all the available tags when updating a dependency for example. It was maybe not much of an issue with projects using more custom code (like a Symfony project) but with Drupal, we use A LOT of contributed code in our projects. I worked on some projects that used way too many modules (more than 200 modules), so imagine if Composer has to fetch and check every tag on every module. That can be an issue with some Drupal projects.

The more dependencies, the slower.

How to avoid Composer's poor performance?

Update specific packages, not everything. Use $ composer update drupal/panels --with-dependencies Not $ composer update

You are using Vagrant? Execute composer from your local, not the VM.

You are using Docker? Execute composer from your local, not the container.

Use PHP 7 with Composer

Benchmark composer performance
Composer performance with parameters and with HHVM (credits to Arnold French - dsdeiz)

The benchmark above shows performance results using:

  • Default configuration (normal).
  • The prefer-dist parameter, when available. In our case it did not make it faster.
  • Using fixed-versions: Instead of using ranges in your composer.json, we tried using fixed version. It made our composer execution a bit faster as Composer did not check every tag on the dependency (as previously mentioned).
  • Using HHVM: You can run Composer using HHVM and this speeds up the process.
  • I would add PHP 7: Similar results as HHVM would be possible using PHP 7. I recommend using this option.

Use Composer, the right way

Make use of this great tool, but keep in mind: start your project the right way (use a template) and make sure you target the right package when updating. Again, Composer is not perfect and comes with some limits in terms of speed. But this is the way modern development is moving towards to, so make sure it makes you work faster and not slower.

 

Presentation "Introduction to Composer for Drupal"
Click to checkout the presentation "Introduction to Composer for Drupal"

 

Join the conversation

Luc Bézier

Consultant Solution Architect