Production Build
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeDuring development, we are not minifying our assets: yep, they're full of comments and spaces. And that's perfect for development! I like spaces! And those comments might be useful! Also... minification takes extra time, so we don't want to slow down our builds unnecessarily.
In other words, while developing, no minification! But for production, yes minification! That means that - somehow - we need to be able to pass a flag to webpack.config.js
that tells it to compile in dev or production mode.
Using NODE_ENV
Tip
If you are using Webpack 4 or higher, use this to configure the Webpack mode:
// webpack.config.js
//...
const webpackConfig = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
//...
}
In Node applications, there's a standard way to signal the environment to your apps: by setting an environment variable called NODE_ENV
. To read this, you can say process.env.NODE_ENV
:
// ... lines 1 - 8 | |
console.log(process.env.NODE_ENV); | |
// ... lines 10 - 135 |
Let's log that. Run webpack like normal:
./node_modules/.bin/webpack --watch
Ok! It prints undefined. So... how do we set that? On a UNIX system, prefix the command:
NODE_ENV=production ./node_modules/.bin/webpack --watch
Yes! It prints production
. If you're on Windows, there's a library called cross-env that can help do this.
The point is: we can now send a flag into Webpack to tell it the environment.
Minify JavaScript
Awesome! Let's use this flag to minify our JavaScript first, via a plugin.
Start by replacing module.exports
with a new variable: const webpackConfig =
:
// ... lines 1 - 33 | |
const webpackConfig = { | |
// ... lines 35 - 131 | |
}; | |
// ... lines 133 - 140 |
Then, all the way at the bottom, export this: module.exports = webpackConfig
:
// ... lines 1 - 33 | |
const webpackConfig = { | |
// ... lines 35 - 131 | |
}; | |
// ... lines 133 - 139 | |
module.exports = webpackConfig; |
Before that, add an if statement: if process.env.NODE_ENV === 'production')
, then we will add a new plugin. So, webpackConfig.plugins.push()
then new webpack.optimize.UglifyJsPlugin
:
// ... lines 1 - 33 | |
const webpackConfig = { | |
// ... lines 35 - 131 | |
}; | |
if (process.env.NODE_ENV === 'production') { | |
webpackConfig.plugins.push( | |
new webpack.optimize.UglifyJsPlugin() | |
); | |
} | |
module.exports = webpackConfig; |
Tip
This is for Webpack 4 or higher. At first, install terser-webpack-plugin
and then use
the following configuration
// webpack.config.js
//...
const TerserPlugin = require('terser-webpack-plugin');
//...
if (process.env.NODE_ENV === 'production') {
webpackConfig.optimization.minimizer = [new TerserPlugin()];
}
And... that's it!
Try it! Run webpack without the NODE_ENV flag first:
./node_modules/.bin/webpack --watch
Ok cool. The un-uglified layout.js
file is 1.62 megabytes. Stop and re-run in production:
NODE_ENV=production ./node_modules/.bin/webpack --watch
Ahh... this takes longer to run! But, the JavaScript files are way, way smaller!
Open up the built login.js
. Ah, yes, one beautiful, single line.
Tip
License comments from outside libraries are not removed from the Uglified files for legal reasons. To remove them, see the extractComments option.
Adding package.json scripts
But, remembering this long command is a bummer. Heck, the command was already long, before adding the NODE_ENV
stuff! My fingers are so tired...
There's a great way to improve this. Open package.json
. Add a new key called scripts
set to a hash. Inside, you can put something like dev
set to NODE_ENV=dev webpack
:
{ | |
// ... lines 2 - 7 | |
"scripts": { | |
"dev": "NODE_ENV=dev webpack", | |
// ... lines 10 - 11 | |
}, | |
// ... lines 13 - 34 | |
} |
Thanks to that, we have a shortcut! Just run:
yarn dev
Yep, it runs NODE_ENV=dev webpack
! And we don't even need to say node_module/.bin/webpack
: the scripts
know to look there already for webpack
.
Let's add two more: watch
set to the same thing with --watch
on the end. And finally, production
, with NODE_ENV=production
:
{ | |
// ... lines 2 - 7 | |
"scripts": { | |
"dev": "NODE_ENV=dev webpack", | |
"watch": "NODE_ENV=dev webpack --watch", | |
"production": "NODE_ENV=production webpack" | |
}, | |
// ... lines 13 - 34 | |
} |
I love it! Try them out:
yarn watch
Nice! Stop that, and try:
yarn production
The command looks right... and the final JavaScript files are super small.
But! Our work is not done yet: we still need to minify the CSS files... and handle a few other things.
In the Windows Powershell the following command works:
Or alternatively, as already described as video comment