Adding a JavaScript library to a Drupal 8 module so it just works with Composer-managed projects

Wait, what? It’s almost 2020 and there’s no set plan for this?!?

Best i can tell from reading the documentation on package types there’s no way to use Composer to grab a single file, which is all i happen to need.

Since there’s no documented way to link directly to jquery.checkboxes-1.2.2.js i’ll grab the source code as a zip file, which is documented, and just use one JavaScript file in the src/ directory, counting on my own assets packaging code to compress it.

libraries/checkboxes.js/src/jquery.checkboxes.js

Yeah this looks like fun, from https://git.drupalcode.org/project/chosen/blob/8.x-2.x/README.txt … NOT:

The Chosen JavaScript library does not support composer so manual steps are
required in order to install it through this method.

First, copy the following snippet into your project's composer.json file so
the correct package is downloaded:

"repositories": [
  {
    "type": "package",
    "package": {
      "name": "harvesthq/chosen",
      "version": "1.8.7",
      "type": "drupal-library",
      "dist": {
        "url": "https://github.com/harvesthq/chosen/releases/download/v1.8.7/chosen_v1.8.7.zip",
        "type": "zip"
      },
      "require": {
          "composer/installers": "^1.2.0"
      }
    }
  }
]

Next, the following snippet must be added into your project's composer.json
file so the javascript library is installed into the correct location:

"extra": {
    "installer-paths": {
        "libraries/{$name}": ["type:drupal-library"]
    }
}

If there are already 'repositories' and/or 'extra' entries in the
composer.json, merge these new entries with the already existing entries.

After that, run:

$ composer require harvesthq/chosen
$ composer require drupal/chosen

The first uses the manual entries you made to install the JavaScript library,
the second adds the Drupal module.

Note: the requirement on the library is not in the module's composer.json
because that would cause problems with automated testing.

Searched for:

Notes from those that wandered down this path long ago:

Then once we actually get the JavaScript in our site, we need to add it with our module… i searched for “require library drupal 8 module” because i was still in a requirements mindset. Here’s the Drupal 8 documentation: Installing an external library that is required by a contributed module

Similar composer ways keep coming up, even though everyone regards them as hacks, and no one thinks its a solution for contrib modules:

Not much of an answer here…

https://stackoverflow.com/questions/11622711/what-is-the-correct-way-of-adding-css-or-js-libraries-as-dependencies-with-compo

Lightning distribution has chosen to go with Asset Packagist, https://lightning.acquia.com/blog/round-your-front-end-javascript-libraries-composer

including MIT-licensed code on Drupal.org

Policy on 3rd party assets on Drupal.org | Drupal.org

I could have pulled the code into my own file and messed with it if that proved the best approach. That’s good.

Ended up taking this horrible approach for https://gitlab.com/agaric/drupal/checkboxesjs in the interim:

Installation

Until handling of non-PHP third-party libraries is figured out by Drupal, which might never happen, installing this module requires jumping through some hoops:

Step 1: Pre-requisites

Recent versions of the Composer template for Drupal projects have this, but ensure that your project’s composer.json file has composer/installers somewhere in the require section, something like this:

    "require": {
        "composer/installers": "^1.7",

And an installer-path (defined under extra) is set to "web/libraries/{$name}": ["type:drupal-library"], that is, there’s part of your composer.json file that looks something like this:

    "extra": {
        "installer-paths": {
            "web/core": ["drupal/core"],
            "web/libraries/{$name}": ["type:drupal-library"],

Step 2: Define a package for the library

Now, add this to your repositories section, creating that section if necessary:

    "repositories": {
        "rmariuzzo/checkboxes.js": {
            "type": "package",
            "package": {
                "name": "rmariuzzo/checkboxes.js",
                "version": "1.2.2",
                "type": "drupal-library",
                "dist": {
                    "url": "https://github.com/rmariuzzo/checkboxes.js/archive/v1.2.2.zip",
                    "type": "zip"
                },
                "require": {
                    "composer/installers": "^1.2.0"
                }
            }
        }
    },

JSON doesn’t allow the final item in a set to have a trailing comma, so watch out for that, as well as keeping the curly braces matching. I’m sorry, no human being should have to edit JSON files.

I think this can be made easier.

add a composer.json to your github project https://github.com/rmariuzzo/checkboxes.js/issues/32

If it doesn’t end up within the web root, https://www.drupal.org/project/vendor_stream_wrapper can help.

https://github.com/fxpio/composer-asset-plugin

Searched for: