Looking at Drupal 8's JavaScript Changes

I recently had the privilege of speaking at the 2012 edition of BADCamp about JavaScript (JS). This gave me a good chance to talk about something I'm passionate about, but also look at how things will be changing with the newest version of the Drupal platform. I started to hear things about this and that, but what was really happening?

First, things are changing. And I mean that in the general scope of there will be differences between Drupal 7 and Drupal 8, but also the changes are constantly updating. This is par for the course when working on the edge of a new product but let's take a look at a few examples.

Coding Standards

The first thing to be aware of is that JSHint is now used to check the syntax and coding standards of JS files in core. You can see the current JSHint configuration in the issue queue. Many editors can integrate this into your workflow, or you can run it directly from your command line (I personally dig using Node.js and NPM for this). Just like with Drupal coding standards for PHP, this is a recommendation and not a requirement. This will likely make your code better in the long run.

Libraries

Another bit of news is that there are new citizens in core: underscore.js and backbone.js. These libraries are used in a couple core initiaves, so they now have a home in the new core/misc directory. Underscore.js is a set of utilities for making writing JS a bit easier while backbone.js is a framework for using JS at an application level. But more importantly, JavaScript libraries are handled differently than in the past. Drupal will now not assume that you need jQuery, Drupal's JS, or any other libraries by default (kinda). Code now needs to specify that it requires these other libraries and this needs to be part of your JavaScript's "top-level closure". How does this work?

On the PHP side of the platform, your modules will likely have a hook_library_info call that will not only define what JS your module will use, but also what libraries your module requires. Here's an example from the Node module.

/**
 * Implements hook_library_info().
 */
function node_library_info() {
  $libraries['drupal.node'] = array(
    'title' => 'Node',
    'version' => VERSION,
    'js' => array(
      drupal_get_path('module', 'node') . '/node.js' => array(),
    ),
    'dependencies' => array(
      array('system', 'jquery'),
      array('system', 'drupal'),
      array('system', 'drupalSettings'),
      array('system', 'drupal.form'),
    ),
  );

Here the Node module is telling the system that it's going to include a JS file, but that it needs four other libraries from the system. But I also mentioned something fancy sounding called a "top-level closure", right?

Even in Drupal 7, developers have been encouraged to put their code in a closure. But in Drupal 8, you'll also want to include things from the "global" space that you want to use. So to continue taking a look at the Node module, here's the node.js file mentioned above:

/** * @file * Defines Javascript behaviors for the node module. */
(function ($) {

    // code ...

})(jQuery);

This is likely the type of closure most developers are used to, but sometimes modules will need to include even more items. core/misc/tableresponsive.js has this closure:

(function ($, Drupal, window) {
})(jQuery, Drupal, window);

Oh, and you might have noticed one other change: Drupal.settings is now drupalSettings. This will allow developers to use this settings functionality without including anything in the Drupal namespace.

Get Involved

These aren't the only things changing. And there is a lot of work to be done and many places that could use some extra hands. If you want to get involved, there is a meta issue for some of the cleanup going on.

Drupal Drupal Planet JavaScript

Read This Next