The composer replacements managed by Yireo have gotten a face-lift. Well, actually not the replacements themselves, but the way to apply them to your project: Meet the composer replacement tool: A composer plugin with its own replace
CLI to help you manage things.
The replacements
For some time, I've been maintaining meta-packages for Magento that allowed for the composer replace
trick to be applied to remove Magento modules that are needed. In short, the trick allows for adding a new entry to a composer.json
file (like below) which then replaces one package with another. When the version identifier is set to *
, the package foobar
(like in the example below) is actually removed:
{
"replace": {
"foobar": "*"
}
}
This trick allowed for removing Magento packages that are not needed by specific projects. And for some time, I have been maintaining meta-packages that allow for bulks of these replacements to be applied. There is a meta-package for GraphQL, there is a meta-package for MSI, another one for Page Builder, third party bundled extensions, content staging, etcetera.
The limitations
However, the meta-packages have some limitations: Either you use them as-is, or you don't. For instance, if you want to remove all MSI packages but keep a few, the meta-package doesn't serve you well. Usually, this means that you disregard the meta-package and copy all of the replace
lines to your own root composer.json
.
Also, there could be a conflict between one meta-package and another, for instance if they both replace the same package: You can't replace a package twice.
A new composer plugin
The new Magento Composer Replacement Tool fixes these issues. The concept is actually to no longer install any of these meta-packages as a composer package anymore, but to use the new composer tool to merge the meta-package into your own replace
section in your own root composer.json
.
The tool is actually a composer plugin that adds a new series of commands to composer
, all starting with replace
(for instance, composer replace:validate
). Via these commands, your own replace
section is managed more effectively.
An example: Removing the Multi Source Inventory modules
As an example, let's say you have been using the package yireo/magento2-replace-inventory
to remove all MSI packages. First, you would install the new composer tool:
composer require yireo/magento2-replace-tools
Next, the tool allows for a new command replace:bulk:add
to be used to import the bulk of yireo/magento2-replace-inventory
as an additional configuration of your composer.json
file (extra.replace.bulk
in this case):
composer replace:bulk:add yireo/magento2-replace-inventory
Once you have configured a bulk package, it is best to validate all of the replacements, before rebuilding things. The validation compares your current replace
rules with the ones described by the extra.replace.bulk
section in the same file. If there is a mismatch, it is reported. With the replace:build
command, you actually follow up on this, wiping out the current replace
section and adding a new section from scratch.
composer replace:validate
composer replace:build
One of the warnings during validation is that the original meta-package should no longer be required. It is swapped out for the configuration instead, so can be removed:
composer remove yireo/magento2-replace-inventory
Finally, the composer.json
has been updated with all of the composer replacements needed. And therefore, the last step is to actually install everything. Sometimes a simple composer update
is enough. However, because of all dependencies needing to be recalculated, I personally favor doing this the more drastic way:
rm -rm vendor/ composer.lock
composer install
General purpose commands
The magic is basically in the new extra.replace
configuration section managed by this new composer plugin tool. First of all, adding new replacements, listing them, removing them, etc, can all be done via a series of commands, that will work in any composer project:
composer replace:list
composer replace:add foo/bar
composer replace:remove foo/bar
Bulk packages, includes and excludes
However, the real goal for this new approach is to allow for the original meta-packages to be be used, but to manage this without conflicts and shortcomings. In your own root composer.json
you can add replace
rules, but you can also require
another package that also has replace
rules. This leads to issues. Instead, the new approach is to install such a replace
package as a bulk package using composer replace:bulk:add
instead.
But what if the bulk package includes a specific package foo/magento2-bar
that you don't want to replace (so: you want to use it)? Answer: exclude that package from replacement:
composer replace:bulk:exclude foo/magento2-bar
What if you are replacing all MSI packages, but you also want to remove a package foobar/magento2-inventory
? Then make sure to include this into the replace configuration, so that it is replaced on top of all of the bulk packages:
composer replace:bulk:include foo/magento2-bar
Hope you like it
So far, I have not found many issues with this new approach. The new CLI commands allow for adding the replacements in a scripted way (I have been adding this already to CI/CD pipelines and Magento demo-builds). And the bulk-packages are now even more useful, because the new approach allows you to include and exclude whatever you need.
Let me know if you like it or not. And if you feel that anything should be improved, feel free to post an issue on the GitHub repository pages.
About the author
Jisse Reitsma is the founder of Yireo, extension developer, developer trainer and 3x Magento Master. His passion is for technology and open source. And he loves talking as well.