Building a Drupal 8 Website with Composer
One of the many Drupal-specific tools we've had in the past has been Drush Make. While Drush Make is still a valid tool for building Drupal 8 websites, I believe Drupal's adoption of Composer is one of the biggest wins in the Drupal 8 release cycle.
Composer is widely used across the PHP community for dependency management. In Drupal 7, it's been becoming more common for Drupal modules to rely on the Composer Manager module instead of the Libraries module to install and manage libraries that can be installed via Composer. Managing third-party dependencies with Libraries was often a pain point in the development workflow, and Composer Manager improved on that by letting us leverage Composer. However, that still created an extra step in building and deploying code in that you had to tell Drupal to rebuild Composer Manager's composer.json file when dependencies changed or were updated.
Only recently has Drupal's core composer.json been separated to only manage core and allow developers to manage the composer.json file in the root directory. There are two packages related to Drupal core - drupal/core and drupal/drupal. The former only installs Drupal core and it's dependencies, while the latter also provides the necessary framework (including index.php) for building a Drupal app.
To get started, we'll first need to create our project. Since the normal Drupal index.php and structure is fine in our case, we'll just create a drupal/drupal project.
composer create-project drupal/drupal my-drupal-8-app 8.0.0-beta12
Depending on your connection and your machine, creating the project may take a while.
After the project is created, you will want to update the composer.json file in the project root to use the Drupal Packagist repository so that you can use packages from Drupal.org. The Drupal Packagist project parses Drupal.org projects and provides a resource for Composer to download them. Of course, this is not necessary if none of the modules that you are using are not at the normal Packagist site, but odds are you will be wanting packages from Drupal.org. You'll also see that we added a couple of modules: OPcache (8.x version not being package on Drupal.org at the time of this post) and Panels.
{
"name": "drupal/drupal",
"description": "Drupal is an open source content management platform powering millions of websites and applications.",
"type": "project",
"license": "GPL-2.0+",
"require": {
"composer/installers": "^1.0.20",
"drupal/core": "~8.0",
"drupal/opcache": "dev-8.x-1.x",
"drupal/panels": "8.3.0-alpha12"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"preferred-install": "dist",
"autoloader-suffix": "Drupal8"
},
"extra": {
"_readme": [
"By default Drupal loads the autoloader from ./core/vendor/autoload.php.",
"To change the autoloader you can edit ./autoload.php."
]
},
"repositories": [
{
"type": "composer",
"url": "http://packagist.drupal-composer.org"
}
]
}
Next run "composer install". As you watch the installation, you'll notice that a library that was not specified (crunch/fastcgi) was also downloaded. This is a library required by the OPcache module to make direct connections to FastCGI servers for managing OPcache. This shows the real power of Drupal 8 leveraging Composer. You don't need Composer Manager to manage the third party code that your modules depend on. You don't need to go through the hassle of manually updating libraries managed by the Libraries module. All you need to do is run composer update in your project root.
You'll also notice that only the Panels module was specified, but it's dependencies (Page Manager and Layout plugin) were also downloaded. This is because Drupal Packagist parses the .info.yml files and provides those dependencies for you in a way that is compatible with Composer.
This is a huge win for DX in Drupal 8. All Drupal module developers whose modules rely on third party libraries that are installable via Composer should (must, in my opinion) include a composer.json file in their project.
Keep in mind that there are still a few issues with this process. Though Drupal currently maintains all of it's core dependencies in /core/vendor, Composer still goes out and downloads them to /vendor. That's not a huge deal because the autoloader loads the right files, but it can cause confusion in an IDE.
Relying on Drupal Packagist also creates yet another #DrupalWTF in my opinion. There is already a perfectly good service out there for managing Composer packages (Packagist). The only thing really holding the Drupal community back from using that is the lack of adoption of semantic versioning in contrib. Hopefully, that will change soon.