Composer Manager allows contributed modules to depend on PHP libraries managed via Composer.
Composer is a command line tool for installing PHP libraries and their dependencies on a per-project basis. Nowadays, all libraries are registered on Packagist and expect to be installed via Composer. See the Composer Getting started page for more information.
How does it work?
Composer expects each project (Drupal installation, in our case) to have a single composer.json file listing all required packages.
Composer Manager allows each contributed module to ship with its own composer.json file, listing the module-specific requirements. It then merges the requirements of all found modules into the consolidated composer.json file, consumed by composer install/update. This results in a single vendor directory shared across all modules which prevents code duplication and version mismatches.
- Using Composer Manager to get off the Island Now (Applies to 6.x-1.x, 7.x-1.x, 8.x-1.0 alphas)
- Managing D8 module dependencies with the new Composer Manager (Applies to 8.x-1.0-beta1 and later)
Frequently asked questions
Why can't we just run "composer install" in each module's root directory?
We'd end up with a vendor/ directory per module, and an autoloader per module. Composer disallows this for a reason:
- Duplicate library code when modules have the same dependencies
- Unexpected classes being sourced depending on which autoloader is registered first
- Potential version conflicts that aren't detected since each installation is run in isolation
To highlight the challenges, let's say module_a requires "guzzle/http": "3.7.*" and module_b requires "guzzle/service": ">=3.7.0".
At the time of this post, running composer install in each module's directory will result in version 3.7.4 of guzzle/http being installed in module_a's vendor/ directory and version 3.8.1 of guzzle/service being installed in module_b's vendor/ directory.
Because guzzle/service depends on guzzle/http, you now have duplicate installs of guzzle/http.
Furthermore, each installation uses different versions of the guzzle/http component (3.7.4 for module_a and 3.8.1 for module_b). If module_a's autoloader is registered first then you have a situation where version 3.8.1 of \Guzzle\Service\Client extends version 3.7.4 of \Guzzle\Http\Client.