Webpack Plugins we been keepin on the DLL

Toward the end of 2015 Eric Clemmons wrote Javascript Fatigue which really hit on something a lot of people were struggling with at the time. This inspired me to experiment with different approaches to make development with Webpack and React easier.

One of the biggest pain points at the time — and still — is that there are so many dependencies, configuration files, build tools, etc. If you are somebody who works on a lot of different projects, this gets annoying quickly.

A lot of developers responded by creating boilerplate projects which can be really helpful. ( My favorite is React Boilerplate by Maximilian Stoiber) I wanted to take a different approach. Rather than having a project you clone over and over every time you wanted to start a project, what if you could have one module that you installed globally that had all of the common dependencies, build tools, configuration, etc? You could use this to load a folder containing your project specific code, instead of duplicating non-project specific things across dozens of different folders.

I am writing now because I want to tell you about an accidental discovery I made while exploring this approach: a technique that is so amazing, yet so undocumented and so rarely talked about. A technique which until recently has not made an appearance in any of the boilerplates that I have found. A technique you can now find by default in React Boilerplate.

I’m Talkin about the Webpack DLL Plugin.

One of the immediate effects of my everything and the kitchen sink strategy was that Webpack build times were excruciatingly slow. In my project that uses React and React Bootstrap, starting up a project might take 20–30 seconds and that is a pretty large window to get distracted and end up on Hacker News.

So I decided to google ‘webpack build performance’ and I found a mention of something called the DLL Plugin. This made me laugh because back in the day when I was a little prototype, I started off building and fixing PC’s and laptops. Doing this exposed me to a lot of the internals of the Windows operating system and system software, and anyone who has spent time in this purgatory has run into their fair share of DLL files. Not being a software developer, I never learned what exactly they did and for the most part forgot about them.

So when I saw the name ‘DLL Plugin’ I had to learn more about it mostly because it gave me a chuckle and brought back memories. I had no idea how amazing it would be or what an impact it would make. After googling more about it and searching, I found very little in the way of examples or discussion about pros and cons. The documentation itself is very sparse and just has an example or two, so it took me a while to get a working configuration.

The first time I did I saw how quickly my project started up. I was shocked. This couldn’t be right. Something was broken.

Nope. Everything was great.

What was broken is how I was using Webpack in development, how many of you are probably still using Webpack in development today.

I highly encourage you to try out the DLL plugin. The improvements it makes to both project startup times and in hot-reload times are no joke.

I will leave it to the benchmark nerds to quantify these things in more detail, but I experienced improvements in startup time from about 18–20 seconds on average down to 3-4 seconds in the same project without anything else changing.

What is it?

Every time you use Webpack to start your development server, it analyzes all of your code to find your require and import statements and from these it builds a table of all of your module dependencies and where the files can be found.

Since we live in an age of unprecedented collaboration and sharing, most of our project’s code lives in modules written by other people. Most of this code we never have to write or touch. And yet, the way most of us have been using Webpack, it is as if this code might change every day and so we need to analyze it every time we start up our environment.

Aint nobody got time for that

The DLL plugin introduces a separate step in the project build toolchain. Whenever your dependencies change — which is probably not that often — you build a DLL which consists of a JSON manifest and a javascript bundle that wraps all of your dependencies up in a neat package.

In your day to day development, you include the DLL Reference plugin and point it to these files. You give your Webpack compiler a break, and you jump right into development seconds after typing `npm start`

A Brief Example

Webpack configuration like the one below will create the DLL. I’ve bolded the important part

module.exports = { 
context: process.cwd(),
  entry: {
ReactStuff:[
'react',
'react-dom',
'react-router',
'redux',
'react-redux'
],
BootstrapStuff: [
'bootstrap',
'react-bootstrap',
'chartjs',
'skypager-themes!skypager-themes/packages/dashboard-dark'
]
},

 output: { 
filename: '[name].dll.js',
path: outputPath,
library: '[name]',
},

plugins: [
new webpack.DllPlugin({
name: '[name]',
path: join(outputPath, '[name].json')
})

]
};

Now once this DLL is built, you don’t need to touch it again unless you change the dependencies or upgrade their versions. Just reference these files in your development server configuration.

{
plugins: [
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(join(outputPath, 'ReactStuff.json'))
},
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(join(outputPath, 'BootstrapStuff.json'))
},
  ]
}

Good Luck and Godspeed.

I wanted to write this post to draw attention to this hidden gem of a Webpack plugin. I hope it saves you some time, even if it is just thirty seconds here and there. May that time add up to hours and hours.

I also wanted to write this post, naturally, to draw attention to myself since I’m always trying to make that paper.

So if your software processes are broke and you’re not, email jon@chicago.com. I help programmers overcome Javascript Fatigue and become productive with React.