Webpack 4 course – part five. Built-in optimization for production

JavaScript Webpack

This entry is part 5 of 8 in the Webpack 4 course

In this part of the Webpack 4 course, we will focus on increasing the experience of users of your application by making our output smaller. This will mean handling the code in a different way in the production environment. Today we will explain the built-in optimization in Webpack achieved by the mode parameter, so let’s go!

Webpack 4 course: why optimize code?

First, let’s answer the question of why would you want to optimize your code at all. If you follow good practice, you probably aim for your code to be easily readable, therefore you add a lot of whitespaces (tabs, spaces, newlines) and comments. While it improves your code, it makes your files bigger. On the other hand, sacrificing readability for the sake of user experience is not the way to go. Doing it manually would be cumbersome. Because of that, there are solutions that you can just pick up and use in your project.

Mode: production

The mode is a parameter that Webpack 4 introduced. The configuration requires specifying it ever since. Not doing it will cause a warning and its value will fall back to the default value, which is production. If you use  , Webpack will set some configuration for you. As a result, your output code will better fit the production. We will now walk through what it exactly does for us.

UglifyJsPlugin

Setting your mode value to production will add the UglifyJsPlugin to your configuration. It can make your code shorter and faster by compressing and minifying it. From tasks as simple as shortening your variable names and removing whitespaces to deleting redundant code. By default, it will parse every .js file. In this article, we will go through the most basic configuration of the UglifyJSPlugin. Even though Webpack 4 runs the optimization for you depending on the chosen mode, you can still configure it through the optimization property.

webpack.config.js

The most crucial property that you can pass to the UglifyJsPlugin is called uglifyOptions. It has a lot of default configuration. One of the most noteworthy parts is the compress property.

It is responsible for configuring a lot of heavy lifting done by the UglifyJsPlugin regarding making your code shorter and lighter. For a complete list of possible options check out the official list. It also marks the default values.

Another important property of the UglifyJsPlugin configuration is the output.

The code generator tries to output the shortest code by default. You can change that behaviour by changing the output configuration. You might not be tempted to change most of the default configuration, but a property worth considering is the drop_console, which is set to false by default. Changing it to true will erase all of your console.log calls. If you would like to know more of the output properties, check out the complete list.

The UglifyJsPlugin has a lot more configuration possible. You can read it all in its documentation on Github.

DefinePlugin

This plugin allows you to create global constants resolved at compile time. If you use  , webpack will set   by default:

webpack.config.js

Note that due to direct text replacement, the value given to the property must contain actual quotes. This can be done by   or  .

Resolving it at the compile time means that if you ever use process.env.NODE_ENV in your code, it will be replaced by the value production.

Keep in mind that the process.env.NODE_ENV value is not kept after compiling the code. Running the code above in with webpack will result in:

After minification done by UglifyJSPlugin, it can be simplified.

NoEmitOnErrorsPlugin

Using this plugin will help you deal with errors during the compilation. For example, there might be a situation in which you try to import a file that Webpack can’t resolve. In this situation, Webpack creates a new version of the application with the information about the error. With the usage of NoEmitOnErrorsPlugin, this version is not created at all.

webpack.config.js

ModuleConcatenationPlugin

By default, Webpack wraps each module in your bundle in individual function closure. These wrapper functions will make it a bit slower for your JavaScript to execute. Check out this example:

one.js

two.js

index.js

Without the ModuleConcatenationPlugin, the output bundle will look like that:

main.js

When you set your mode to production, the plugin starts doing all the work. Thanks to this, the output bundle is now in one scope. Fewer functions mean less runtime overhead.

Note, that I am not using any minification in this example. Thanks to the fact that minimizer now knows about inter-module dependencies, it could do a better job.

main.js

If you find it interesting, check out the article on the webpack blog that announces this feature for more information.

Summary

Today we’ve learned about the built-in optimization that Webpack can do with  . This can make your application load faster and perform better. It is achieved by undergoing a set of processes configured to suit the production needs. In the next part of the course we will cover the development configuration of the mode, so stay tuned!

Series Navigation<< Webpack 4 course – part four. Code splitting with SplitChunksPluginWebpack 4 course – part six. Increasing development experience >>
Subscribe
Notify of
guest
4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
hua
hua
5 years ago

for the DefinePlugin, if you only config ‘process.env.NODE_ENV’. it is not needed in webpack 4. set mode value will do it for you.

https://webpack.js.org/concepts/mode/#mode-development
https://webpack.js.org/concepts/mode/#mode-production

john
john
5 years ago

It seems that Webpack 5 will favor Terser over Uglify, due to better performance and package maintainability

Mike
Mike
4 years ago

The code generator tries to output the shortest code by default. You can change that behaviour by changing the output configuration. You might not be tempted to change most of the default configuration, but a property worth considering is the drop_console, which is set to false by default. Changing it to true will erase all of your console.log calls. If you would like to know more of the output properties, check out the complete list.

drop_console is a property of Compress options, not Output options.