Best practices for handling external libraries in Drupal 8/9/10 and 11

Created on 30 October 2015, about 9 years ago
Updated 6 September 2024, 3 months ago

The Backstory

While talking to @webchick at BADCamp, I (samuel.mortenson) brought up that even with Drupal 8's new Library handling logic, there is still no answer to/best practice for one of the most common Library problems: "Where do I put my external Javascript/CSS files?". I can think of a few approaches to this, but we should standardize as a community on one or more best practices so that contributed module authors know the best methods for handling external libraries.

The stories that need to be worked out in the documentation are:

  1. As a module author, I need to know what best practices to use when including external libraries.
  2. As a module author, I need to deal with duplicate versions of libraries and conflicts with other modules.
  3. As a module author, I need to verify library versions and warn users when libraries are out of date.

Your behaviors—Adding JS/CSS in a module or theme

Best practices for handling External Libraries using Libraries API

Ultimately, the goal of the Libraries API is to make the assets added by it shareable between modules and themes, consistently done between projects and developers/sitebuilders — and it is easier to maintain through the lifespan of a site.

    • With the Libraries module (3.x) for Drupal 8 . Having contrib modules for each external common JS framework (and then, plugins of that framework), and mark those as a dependency of your module/theme.
    • Use hook_libraries_info() to define a new library, use DRUPAL_ROOT/libraries as the general folder to uncompress those packages. Use a subfolder name reflecting that JS framework/plugin (e.g., /libraries/jquery.easing).

      DRUPAL_ROOT is the PHP Constant name for your web root folder where the other files (like index.php) would be found.

    • For multisite projects where you many want to limit to a unique site use DRUPAL_ROOT/sites/[domain]/libraries.
  1. Add [my_module].install file in your module. Use hook_requirements($phase) with a loop for if ($phase=='install'){} to check for proper installation of Library.
  2. Would be best to give as direct a link to the library. (ie if from github give path to the tagged version you know will work with the drupal behaviour that will be triggering it. do not just link to MASTER/HEAD, unless you want a string of issues against your module because the plugin has changed!

Some Aside Notes

  • On Tools of the trade:
    • Let's not focus on how a developer/site builder downloaded to their file system, as there is a variety of tools to do so and will change in time. (ie: no one uses MAKE files anymore)
  • Linking from 3rd party Servers:
    • Not recommending module developers linking CDN's in their *.libraries.yml file. This is a poor development practice, you can't guarantee your module/theme's functionality this way.
    • Problems with 3rd services (CDN's or general linking to other live Servers) with 404 & maintenance realities or just slow load times..
    • Some issues on the effects on js/css caching can occur with CDN use.
  • Why not to include 3rd files in a Drupal Repo

    RE: Regarding Software Licenses. Drupal.org's policies and other legal requirements

    Simply, if we use the Libraries API (and only include the JS behaviour and custom CSS in our modules/themes) we will be in compliance with such policies and laws. Making such 3rd code sharable and maintainable in our custom work for clients. As well as then being ready to contribute work back to the Drupal Community.

    Related Issues on Drupal core — Themes:

    1. Add (back) hook_install for themes
    2. Allow themes to declare dependencies on modules
    📌 Task
    Status

    Active

    Component

    Missing documentation

    Created by

    🇺🇸United States samuel.mortenson

    Live updates comments and jobs are added and updated live.
    Sign in to follow issues

    Comments & Activities

    Not all content is available!

    It's likely this issue predates Contrib.social: some issue and comment data are missing.

    Production build 0.71.5 2024