Using civicrm/composer-compile-plugin to compile JavaScript in a PHP library

I have a PHP component, miklcct/journey_recorder, which can be used either as a standalone website or as part of another site. It started initially as a pure PHP component which does all work server-side and outputs HTML to the browser, but over time JavaScript has been added as a form of progressive enhancement, while retaining the usability without it.

At first, it was just a single script file which used jQuery but nothing else, so I used the old fashioned way to include jQuery and my script file in script tags of the HTML, but over time I started to add more libraries including form serialisation and date picker, and introduced a service worker to provide offline functionality as well, so the old fashioned way of loading libraries from a CDN is no longer maintainable.

I then introduced a dependency manager (yarn) and a build system (esbuild) into the project and got it working when the PHP component was used as a standalone application, but how can I build the JavaScript automatically even when the component is a dependency of another application? Composer does not offer a built in way to run scripts in dependencies, and it is understandable because it is a security risk to allow third party libraries to run arbitrary programs as part of regular updates.

Fortunately this problem is common enough that a Composer plugin has already been written, which is called civicrm/composer-compile-plugin. By adding it as a dependency of the library, it allows library developers to include a build step, and if an application uses the library, the plugin prompts the user to run the build script (or automatically if the library is trusted).

The usage can be as simple as:

{
"require": {"civicrm/composer-compile-plugin": "~0.14"},
"extra": {
"compile": [
{"run": "@sh cd css; cat one.css two.css three.css > all.css"}
]
}

So I put in two build steps into it, one to install the JavaScript dependencies using yarn, and the other to build the JavaScript bundle for browser consumption.

The job is now done. When the application includes this library, after composer install, the JavaScript bundle is now ready to be used by the client.

Leave a Reply

Your email address will not be published. Required fields are marked *