#65305 closed feature request (duplicate)
Finally include Composer in core and allow plugins to opt in.
| Reported by: | mmorris8 | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Plugins | Version: | |
| Severity: | normal | Keywords: | |
| Cc: | Focuses: |
Description
Wordpress is the last major PHP application that doesn't use Composer at a core level. I believe that should change for the benefit of the community and can change without making the application harder to install and use. I went through the top ten pages of trac tickets and didn't see one on this topic, so here we are.
What is Composer?
Composer is frequently called a package manager, but more accurately it is a dependency manager. It was inspired by node.js' npm and ruby's bundler. PHP libraries distributed on Composer can recursively include the libraries that they need. Composer resolves shared dependencies between libraries and tracks versioning. For more on this: https://getcomposer.org/doc/00-intro.md
Background
A Google search "WordPress composer" brings up multiple integrations outside the core. These inclusion works, but the quality is uneven and can confuse or intimidate new developers, to say nothing of end users. Further, plugins that want to use Composer libraries currently need to ship a copy of all their dependency code in order to install. Some plugins have taken the further step of using Strauss or similar monkey typing libraries to avoid name collisions when two different plugins try to load the same dependency.
A bit about me. I used to work extensively with WordPress from 2008 till 2013. I left it and PHP behind until my most recent job where I’ve spent the last couple years with three WordPress sites under my supervision. I’ve gotten reacquainted with the plumbing, been pleasantly surprised to see React heavily in use on the admin side and worked through building new modules and blocks at the end level. Because of my Symfony and Drupal background I’ve been using the Timber/Twig library and have composer hacked in relatively painlessly by using the must use plugin in directory and picking filename “00_autoload.php” to force composer to load before anything else. Many years ago I worked on testing the composer integration into Drupal 8 and have contrib credits with that application, primarily the Runtime Assertion library.
What is solved with Composer?
Composer is the dependency manager for PHP. It has eclipsed Pecl because it allows projects and applications to have their own dependencies, not require a global install of the dependency library on the server (a non-starter on shared hosts). There's a lot of libraries out there, including the entirety of Symfony, Laravel, Drupal which can be composer installed. The power of this interoperability is immense.
As an end administrator I can use composer quite freely as outlined above. My own plugins can presume it's there, and I can hand modify the composer.json file at the project root. Problems would immediately arise if I tried to ship my plugins for others to use. I'd have to ship the code my plugin uses with it. More seriously, if another plugin uses a shared dependency a name collision will occur unless Straus is used to monkey type the entire library (which is glitch prone as PHP code is being redefined on the fly).
Proposed, a new way to load composer aware plugins.
The solution to these problems is to make Core at least aware that composer is a thing and allow Plugins to opt in. These plugins will have to have a json file that composer understands, and my proposal is to follow a pattern similar to Drupal Extensions. Drupal scans each extension's composer.json file and merges them to create a master file that composer interacts with to install and update the site (or at least it did in 8. They're up to version 11 now)
This approach is also not unlike the introduction of the block.json file for blocks. Since we do not want composer to errantly run a plugin's composer.json we should use a different name - plugin.json
The foundation spec for these will be the composer.json schema: https://getcomposer.org/doc/04-schema.md
But in addition to that markup we can provide WordPress specific information.
Hooks
Hooks can be called out in the plugin.json. Composer libraries are Object Oriented, so callback references would be used.
{ "hooks": [ { "activation": {"ExamplePlugin\\Installer", "activate"} }, { "deactivation": {"ExamplePlugin\\Installer", "deactivate"} }, { "uninstall": {"ExamplePlugin\\Installer", "uninstall"} } ] }
Install Process
The install process of composer aware plugins will need to be slightly different from the current plugins to account for composer. A draft overview of the steps for a new plugin.
- The plugin.json file's require property will be checked against the require property of all currently installed plugins. If two plugins call for the same dependency, the new plugin must allow a compatible version range to the existing - that is the same major version number. If the plugin specifies a specific version number (not advised) then the whole number must match.
- Provided all dependencies are compatible the require list will be appended into the master site require list for composer to process.
- Require_dev will only be processed if the WP_Debug flag is set to true.
- Hooks from the plugin and any dependencies with hooks will be registered.
- Composer will then run and fetch the libraries. As normal, they'll live in the /vendor directory at site root.
- WordPress will process composer aware plugins after normal ones.
Final thoughts for now
The reason to handle this at core is to allow plugins to use composer without needing to worry about other plugins doing the same. Conversations about how this could apply to core itself are out of scope. Everything above can also apply to themes.
Thoughts?
Change History (4)
#3
in reply to: ↑ 2
@
7 weeks ago
- Resolution → duplicate
- Status new → closed
Replying to westonruter:
If you look in Trac, there have already been many discussions about how to best use Composer. For example: #21300, #36335, #47256.
I'm not sure we need another ticket.
We don't. I was unable to find those tickets after about a half hour's search though. I've joined watching the last one in the list.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
So, if I take a crack at this, where should composer's master json file go? site root or wp_uploads ? Same question for the vendor directory.
My first instinct is the standard location, but that may not make sense here. Also, composer aware plugins will be composer libries - not plugins - and therefore land in the vendor directory. End users likely won't care, but that could be a confusion point for devs.
Thoughts?