Defining a new way of working with JavaScript in Drupal

woman using large puzzle pieces

There is a growing problem with building Drupal sites and maintaining contributed Drupal modules that use JavaScript libraries, especially if those libraries overlap between modules: Drupal currently has no standard way to install JS dependencies.

Some modules have tried asset-packagist, but there have been problems with that service suffering timeouts or going offline and sites not being able to deploy during those periods.

I had a whinge about this situation in the #australia-nz channel in Drupal Slack

Post by @Darvanen on Drupal Slack: "Wouldn't it be nice if there was a standard way for modules to define a way to fetch dependent packages in a project like we do with Composer for PHP libraries?"

and Lee Rowlands (@larowlan, core committer) made a generous offer to help get an initiative off the ground, which I grabbed with both hands gratefully accepted.

Where does one even begin?

Lee introduced me to Théodore Biadala (@nod_) the Drupal frontend framework manager and we three had a short discussion around suitable directions to take. An initiative would not be happening without their generous help and guidance, they have both earned my eternal thanks.

We explored the idea of using import-maps to let the browser handle module imports and agreed that the cascading downloads would be an unacceptable performance burden.

The result of that meeting was the idea of trying out publishing Drupal modules on npm, or at least an npm-like repository, since Lee mentioned that GitLab can provide one. I got started and wrote some scripts for gathering package names and putting them in a central package.json to be downloaded by npm/yarn/whatever.

Then Lee pointed out which I had seen, but didn’t really understand the power of. What I didn’t understand was that you could define a package.json file inside a composer package, make a couple of tweaks to composer.json and without publishing any kind of npm package, foxy would find it and treat it like one.

Cue a couple of weeks of messing around with foxy, composer and vite in spare time, and I have created a working prototype for compiling multiple Drupal modules (including custom modules if desired) in a project, and routing the library system to the new entry points:

Prototype requirements

Any module that wants to opt in:

  • Adds php-forge/foxy to require or require-dev in composer.json.
  • Adds a module-name.foxy.yml file to represent the library state when using foxy.

Site builders:

  • Have one or more modules that use foxy in their project.
  • Require and enable drupal/foxy.
  • Add a provided vite.config.js to their project.
  • Set up a way to run vite build (or their own implementation):
    • post-install/update commands.
    • perhaps in a pipeline.
    • maybe manually.

Aiming for community adoption

The prototype is just a starting point. The aim is for the community to come together to define a new way of working with JavaScript in Drupal that everyone can and will want to use, similar to how drupal-composer/drupal-project pioneered effective usage of composer and was eventually adopted by core. 

The conversation has started in the #frontend-bundler-initiative channel in Drupal Slack, come join us!

There are some things you can do right now:

  • Spread the word, recruit more people to the initiative, especially if they maintain a module with JS dependencies.
  • Try out the prototype and give feedback.
  • Chat in the initiative channel about ways forward.
  • If you have a module with JS dependencies: speak up to have your module included in the prototype, or make a PR.
  • Contribute to the foxy module to get it to import css/image/asset dependencies from the vite manifest.