You can fine tune several webpack plugins to make your bundle as small as it can be for your specific application. However there are a few things you can do for pretty much every application to make it smaller and run faster. In this lesson we’ll combine several webpack plugins to optimize things for a React application (this is also applicable for non-React applications as well).
Webpack comes pre-built with a bunch of optimization plugins that you can utilize by specifying this -p shortcut to the Webpack 2 CLI. If we run the production build as is with the Cameron build prod, it's going to go ahead and build our application using all of the production, optimizations here. We'll see a whole bunch of output.
I've added [inaudible 0:24] application to give us a bit of a better sense of what things will look like in a real application. We see a lot of condition always false or true, removing that code, unreachable code. Webpack is doing this using the Uglify JS plug-in. Here, we see that the final bundle size is 164 kilobytes, and we have a source map here as well.
Just for comparison, if we run the regular build, we're going to see the file size is much bigger. The minified version is 164 kilobytes. The unminified version is 832 kilobytes. For most applications, you'll probably be fine just going with the -p on the CLI.
If you want to be able to fine tune some of the plugins that Webpack is using, or get rid of all that Uglify output, because it makes it really difficult to debug problems. Then you're going to want to specify these plugins yourself. That's what we're going to do in this lesson.
The first thing that we're going to want to do is make sure that we remove this -p. If we don't do that and start adding these plugins to our Webpack configuration, we're going to wind up with double minification, which generally leads to bad bugs in production that are really hard to track down.
We'll make sure we remove it from here in our scripts. Then we'll go ahead and add the plugins in our Webpack configuration. These plugins are available from Webpacks, so I'll require that here. I've added a couple of utility functions here. I'm going to leave their implementation as an exercise for the viewer.
Here we're going to add a plugins array. We'll use that remove empty, so that we don't wind up with any undefined values. The first plugin that we're going to add is the New Webpack.optimize DedupePlugin. This one, we don't actually have to do anything with.
The DedupePlugin essentially looks at all of your modules and determines if any of them are the same. If they are, it will deduplicate those, so you only have one copy of that module in your bundle. This can happen if you're using NPM version 2 to install your dependencies.
If you have two dependencies that have one common dependency between each other, then you'll wind up with some duplicate code. This plug-in will alleviate that program. Next, we're going to say, "If production." If production only plug-in.
This will be "New Webpack.loader options plugin." This one is actually included by default with that -p argument, but it only specifies minimize is true. It will also specify debug is false just to speed up our build times.
The loader options plug-in essentially tells all of our loaders that we're in minimized mode, and they can optimize according to whatever optimizations they can do, or the code that they're loading. I should also note that the loader options plug-in is only available in Webpack 2.
Most of the plugins and the API to Webpack are the same between Webpack 1 and 2, but this is one in particular that's only available in Webpack 2. Next, we're going to add another plug-in that saves us a lot of trouble. That is in production mode also. New Webpack, define plugin process.env.node_nv is production as a string.
What this is doing is it's taking any instance of process.env.nodeenv and replacing it with a string production. That way when React or even in our own code, we say process.env.nodeenv is production. It's going to replace this with production.
It's going to evaluate this as true. In any instance where that value actually ends up being false in an if statement, for example, it can go ahead and remove that code as dead code. That's generally done by the UglifyJS plug-in which we'll add next.
This saves us a ton of space when using React in particular, but it can also save us some space with other libraries as well. I should note also that this isn't just a size optimization, but it's also a performance optimization in the case of React. For example, it will disable runtime checks for your prop types.
Our last one is also if prod. We're going to have a new Webpack, optimize UglifyJS plug-in. We're going to specify compress options. The first one is screw_ie8, true. This is a legitimate UglifyJS option. Then we'll also specify warnings is false.
This will make it that our console is not totally loaded with warnings when we're Uglifying and building for production. With those plugins going, we can run npm run build prod. This will do basically the same thing that it did when we had the -p on the CLI, except, we've been able to fine tune it a little bit, so Uglify doesn't spit out a ton of output.
We've added a couple other plugins as well. These are a couple of plugins you can use to really shrink your build. I should also note that if you're really concerned about size, you should consider using the common strength plug-in. That's a lesson for another day.
In review, all that we had to do here is in our pegasus JSON. We changed our build prod to remove the -p. Then we went into our Webpack config, we required Webpack, added a couple of utility functions for ourselves, added this plugin's array, and added a couple of these plugins for a production build.