Webpack Plugins we been keepin on the DLL

I want to tell you about an accidental discovery I made while exploring different ways to make javascript development less tedious. It is 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 seen. 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 attempts to make javascript less tedious was my Webpack build times became 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.