Progressive Decoupling 3: The webpack module
Progressive decoupling is changing fast, and there’s a lot to talk about since our last blog.
- Allows developers to use ES6 directly in the library JS files
- Uses a single, project-wide package.json (and thus node_modules) for managing npm dependencies
- Makes it possible to import these dependencies directly in the libraries
When considering the same material for a presentation at Decoupled Drupal Days in New York, I decided to try and implement a proof-of-concept. This was motivated both by my desire to see what I could make and my preference for coding over writing presentations.
At the time I had about three full days and one very long flight so I decided to see what I could do. I published the first alpha at seven am on the day of the presentation (what can I say, I was jetlagged).
Since then, eight more alphas have been released. Each one adding new features, fixing bugs, and updating the installation instructions to work with the recently-released babel 7. Just last week we’ve also added webpack to our “Drupal+” composer package called silverback. This means it will be part of every new project at Amazee Labs.
How does it work?
All the libraries that contain this line in the definition will be processed by webpack prior to including in a page. There are two modes of operation, each represented by a drush 9 command.
For local development there’s
It starts the webpack-dev-server under the hood, so the libraries are processed on the fly when any entry file changes. The dev bundle is included directly in Drupal, so you get all the benefits of the mentioned npm package, including live-reload. The command can be run on the host system, as well as in a Docker container. The latter requires some additional configuration (see drush webpack:server --help for details).
When it comes to creating the optimized bundle, or building for production, there’s
The default (and recommended) way of using this command is to execute it on the server at deploy time and store the result in the public files folder. This ensures that no artifacts are committed to the repository.
If for any reason you can’t do it this way then the output path can be changed to an arbitrary folder outside of the public filesystem. In this case there are two caveats:
- Config needs to be exported after every webpack:build - this is required in order for Drupal to know which result files need to be included when a given source file is requested (the default mode uses the state API to store the mapping)
- Conflicts in the output files will be very hard to resolve, so it may cause problems if more than one person is working on the source.
How to install it?
The module can be installed with composer
It requires drush 9 and the yarn executable (that’s because the drupal NPM module only works with yarn at the moment). Each module in the webpack suite also has its own npm dependencies. For the base module these can be installed with
How to use it?
Now that we have all that we can start writing modern js, right? Not exactly, but we’re close! Just like in the JS world, webpack doesn’t transpile the source code - it just bundles the files together with their dependencies and provides a way for other packages (e.g. transpilers) to hook into the process. However, we can import npm modules already. For example, to use lodash in our Drupal library we would need to do two things:
From there, everything is ready. In order to use the newest features of ECMAScript in a browser-compatible way we’ll need the babel package and some webpack config. The former is very simple and can be achieved with:
The latter is usually a bit more tedious, so the required configuration has been bundled into the webpack_babel module.
In the next post, we’ll take a look at the current state of the webpack modules ecosystem and see how to write our own extensions as well as fine-tune settings at a project level. Please feel free to comment, ask questions and give feedback below!