Composer is a PHP dependency management tool. It allows us to specify the third party code (packages) we need in a composer.json
file, and pull them all in with a single command.
Composer uses a "lock file", named composer.lock
. Whereas composer.json
can specify "loose" versions of the packages you need, composer.lock
will always specify exact versions. This allows composer install
to be very fast, and ensures that all developers on the project are using the same versions. As a rule of thumb, any time you change composer.json
, you should run composer update --lock
to regenerate the lock file so the two stay in sync.
**Important: You should never just delete the lock file. If you hit a conflict, see the conflict resolution section below.
Follow these steps to update a package:
composer require drupal/mymodule --update-with-dependencies
git add composer.*
git commit -m "Adding drupal/mymodule"
composer update drupal/mymodule --with-dependencies
git add composer.*
git commit -m "Updating drupal/mymodule to version X"
Note: You may also need to update the version constraint for the package in composer.json
composer remove drupal/mymodule
git add composer.*
git commit -m "Removing drupal/mymodule"
Do not directly remove the package from composer.json
- this will leave any dependencies of your package in composer.lock
, and they will continue to be installed in the future, even though they are not needed.
It's common to run into conflicts in the composer.lock
file. This file cannot be merged by hand. You have to resolve any conflicts using composer. Let's imagine you have a feature branch myfeature
that was taken off of develop
a few weeks ago. You've added a new module on myfeature
, and there's been a new module added to develop
. When you merge develop
back into myfeature
, you will hit a conflict in the lock file. Here's how to resolve that conflict:
git checkout --theirs composer.lock
<- Reset composer.lock to the develop version, throwing out your changes.composer require drupal/mymodule
<- Re-run the exact changes you made in adding your module on the clean lockfile.git add composer.*
git commit -m "Resolve merge conflict in composer.lock"
You need to remember the Composer commands that you used to make your changes initially. Assuming you have those, it's just a matter of resetting the lock file and running them again to resolve the conflict.
Any packages required in the require-dev
section of composer.json
will not be included in the final build that is sent to Acquia. Be very careful not to reference development packages from code that will be run in production.
You should try to use loose version constraints, based on semantic versioning wherever possible. See this article for information on what the tilde and carat do, and this article for a full reference.
Most packages that are used will follow Semantic Versioning. In general, you want to allow either MINOR or PATCH level changes to be pulled in without needing to change the version constraint in composer.json
.
-
Symfony components have been added to
composer.json
as root requirements. This is only to save memory during the update process. It is against best practices to add dependencies of dependencies to your rootcomposer.json
, but the memory and time savings made it worth it for this project. To update these in the future, open Drupal core'scomposer.json
and copy out thesymfony/
dependencies into the rootcomposer.json
-
Use loose version constraints wherever possible. This will allow the version to be updated in the future without changing
composer.json
. -
On occasion,
composer.json
andcomposer.lock
files can get out of sync. In order to prevent this from happening, we enabled CircleCI to runcomposer validate
. This validation process ensures that both.json
and.lock
are in sync and nojson
syntax errors exist. If you get an error that these two files are out of sync, runcomposer update --lock
on your local branch and commit the output of this operation. -
If you have trouble running
ddev composer install
you can try deleting the vendor directory and rerunningcomposer install
to get a fresh copy of the vendor directory: -cd <path/to/mass>
-rm -r vendor
-composer install