TL;DR: On Sunday, February 25, 2018, Webpack 4.0, was released to the public. Legato (Weboack 4.0's codename) is a major release to the JavaScript module bundler. It has taken about eight months since the release of 3.0. In this article, I'll cover the new features in Webpack 4.0 and several other changes and deprecations.

Webpack is a capable module bundler for JavaScript applications. It bundles every one of the modules in your application into at least one file (frequently, only one) and serves it to the browser. In any case, Webpack is something beyond a module bundler. With the assistance of loaders and plugins, it can change, minify and optimize a wide range of files before serving them as a bundle to the browser. It takes in different resources, for example, JavaScript, CSS, Fonts, Images, and HTML, and afterwards changes these assets into a configuration that is helpful to use through a browser. The genuine energy of Webpack is the whole of its parts.

Alright, that's enough, this article provides a gentle introduction to webpack. Now, what's new in Webpack 4.0?

What's new in Webpack 4.0?

1. Node.js 4 Support Dropped

Node.js 4 is no longer supported. The source code was upgraded to a higher ECMAScript version.

Make sure to use node >= 8.9.4 when using #webpack 4 legato.



Older versions will have reduced performance, because we started using newer JS features, which are less optimized in older V8 versions.



Btw. awesome work of the v8 team regarding performance. — Tobias Koppers (@wSokra) February 25, 2018

The creator of Webpack, Tobias, warns users to use Node >= 8.9.4 for optimal performance because of newer JavaScript features now used in the codebase.

2. Farewell CommonsChunkPlugin, Hello SplitChunksPlugin

It's sad to see you go, dear CommonsChunkPlugin . The infamous CommonsChunkPlugin has been removed and replaced with two new smooth APIs called optimize.splitChunks and optimization.runtimeChunk . Let me explain!

Webpack 4 shipped with huge improvements to the chunk graph and a new optimization technique for chunk splitting. A new plugin was born in the process of improvements called SplitChunksPlugin . The SplitChunksPlugin automatically identifies modules which should be split by heuristics and splits the chunks. And it has some other great features such as working efficiently on async chunks, and handling vendor splitting with multiple vendor chunks.

By default, shared chunks will be automatically generated for you out of the box in Webpack 4. And it is configurable via optimize.splitChunks . The optimization.runtimeChunk: true option adds an additional chunk to each entry point containing only the runtime.

Tobias has compelling examples of how the new optimization technique works!.

3. WebAssembly Support Out of the Box

WebAssembly (wasm) is a new portable, and load-time-efficient format suitable for compilation to the web. It's really fast and the developer community is embracing it rapidly. For this reason, Webpack 4 now supports WebAssembly out of the box. In Webpack 4, you can import and export any local WebAssembly module. And you can write loaders that allow you to import C++, C and Rust directly.

Note: The WebAssembly modules can only be used in async chunks.

4. Support for various Module Types

Webpack 4 now supports five module types. These module types are:

javascript/auto: Webpack 3 shipped with support for this module type with all module systems enabled, CommonJS , AMD , ESM .

Webpack 3 shipped with support for this module type with all module systems enabled, , , . javascript/esm: Supports only ECMAScript modules.

Supports only ECMAScript modules. javascript/dynamic: Supports only CommonJS and AMD.

Supports only CommonJS and AMD. json: Supports only JSON data, It's available via require and import .

Supports only JSON data, It's available via and . webassembly/experimental: Supports only WebAssembly modules. For now, it is currently experimental.

5. Lighting the Fire with Mode

I am more excited about this feature than everyone in the universe at the moment. The Webpack team has introduced a new config property called mode all in the quest to achieve a zero-config (#0CJS) module bundler. The mode option can be set to either of these two values; development or production . Out of the box, it defaults to production .

The production option provides a set of sensible defaults that allows for:

Small output size.

Fast code at runtime.

Omitting development-only code.

Not exposing source code or file paths.

Easy to use output assets.

The development option provides a set of sensible defaults that allows for:

Better tooling for in-browser debugging.

Fast incremental compilation for a fast development cycle.

Better error messages at runtime.

Check out the configuration options affected by mode .

Note: Without the mode option in your Webpack config, a warning will be thrown at you.

6. Zero Config Module Bundler #OCJS

Before now, an entry point had to be defined inside a webpack.config.js file for Webpack to bundle your app. However, with Webpack 4, there is no need to define the entry point, it will take ./src/index.js as the default.

Furthermore, there's also no need to define the output file, it emits the bundle to /.dist/main.js .

The significance of this slick feature comes to play when spinning up small projects. No need for a configuration file. Just webpack away!

Webpack 4 without any config and entry file.

Webpack 4 without any config file. Just a src/index.js file.

7. Faster Build Times

Webpack 4's build times are now up to about 98% faster than the previous major version. Don't take my word for it. Try it out yourself. You can get started with Webpack 4 like so:

npm i webpack --save-dev

or use yarn like so:

yarn add webpack --dev

In your package.json's devDependencies section, you should now have:

"webpack": "^4.0.0"

Webpack 3: 2405ms Webpack 3's build time

Webpack 4: 1388ms Webpack 4's build time

Webpack v4 is almost 2x faster than v3 in build time!

Other performance tests from the community can be found below:

6 entries, dev mode, source maps off, using a bunch of loaders and plugins. dat speed ⚡️ pic.twitter.com/fgzYPN24k1 — Evan Scott (@probablyup) February 18, 2018

8. Fresh Plugin System

Webpack 4 ships with a complete overhaul of the plugin system. There is a new simple API for plugins and hooks which comes with the following configuration:

The hooks object houses all hooks as property of the extensible class.

object houses all hooks as property of the extensible class. Multiple Hook classes now exist depending on the hook type: sync , async , normal , bailing , waterfall , looping .

classes now exist depending on the hook type: , , , , , . You must provide a name when adding plugins.

You can choose the type of the plugin (sync/callback/promise) when adding plugins.

this.hooks = { myHook: new SyncHook(...) } is the new way of registering hooks. Creating a new Hook object as a property of the hooks object.

Tobias wrote a comprehensive note on how the new plugin system works. The plugin method is backward-compatible.

9. Giant Move to webpack-cli

The Webpack's command line interface has been moved to webpack-cli, you need to install webpack-cli to use the CLI.

The Webpack CLI documentation can get you started on using the webpack-cli effectively.

Deprecations and Other Updates

These plugins have been deprecated, NoEmitOnErrorsPlugin , ModuleConcatenationPlugin , NamedModulesPlugin . You can now use optimization.noEmitOnErrors , optimization.concatenateModules , and optimization.namedModules respectively.

, , . You can now use , , and respectively. import() always returns a namespace object.

always returns a namespace object. Webpack now removes dead branches by default.

The use of System.import() now emits a warning.

now emits a warning. webpackInclude and webpackExclude are supported by the magic comment for import() . They allow to filter files when using a dynamic expression.

Road to Webpack 5

There are several plans underway for Webpack 5. Some of these plans include:

Stable WebAssembly support.

The ability to create a custom module type and have Webpack support it.

Eliminating ExtractTextWebpackPlugin and supporting a CSS module type out of the box.

and supporting a CSS module type out of the box. Supporting HTML module type out of the box.

Persistent Caching

Aside: Webpack and JavaScript at Auth0

At Auth0 we use JavaScript heavily in development and automate tasks using build tools such as Webpack. Using our authentication and authorization server from your JavaScript web apps is a piece of cake.

Auth0 offers a free tier to get started with modern authentication.

It's as easy as installing the auth0-js and jwt-decode node modules like so:

npm install jwt-decode auth0-js --save

import auth0 from 'auth0-js'; const auth0 = new auth0.WebAuth({ clientID: "YOUR-AUTH0-CLIENT-ID", domain: "YOUR-AUTH0-DOMAIN", scope: "openid email profile YOUR-ADDITIONAL-SCOPES", audience: "YOUR-API-AUDIENCES", // See https://auth0.com/docs/api-auth responseType: "token id_token", redirectUri: "http://localhost:9000" //YOUR-REDIRECT-URL }); function logout() { localStorage.removeItem('id_token'); localStorage.removeItem('access_token'); window.location.href = "/"; } function showProfileInfo(profile) { var btnLogin = document.getElementById('btn-login'); var btnLogout = document.getElementById('btn-logout'); var avatar = document.getElementById('avatar'); document.getElementById('nickname').textContent = profile.nickname; btnLogin.style.display = "none"; avatar.src = profile.picture; avatar.style.display = "block"; btnLogout.style.display = "block"; } function retrieveProfile() { var idToken = localStorage.getItem('id_token'); if (idToken) { try { const profile = jwt_decode(idToken); showProfileInfo(profile); } catch (err) { alert('There was an error getting the profile: ' + err.message); } } } auth0.parseHash(window.location.hash, (err, result) => { if(err || !result) { // Handle error return; } // You can use the ID token to get user information in the frontend. localStorage.setItem('id_token', result.idToken); // You can use this token to interact with server-side APIs. localStorage.setItem('access_token', result.accessToken); retrieveProfile(); }); function afterLoad() { // buttons var btnLogin = document.getElementById('btn-login'); var btnLogout = document.getElementById('btn-logout'); btnLogin.addEventListener('click', function () { auth0.authorize(); }); btnLogout.addEventListener('click', function () { logout(); }); retrieveProfile(); } window.addEventListener('load', afterLoad);

Get the full example using this code.

Go ahead and check out our quickstarts for how to implement authentication using different languages and frameworks in your apps.

Conclusion

You have now learned the new additions to Webpack. Webpack 4.0 shipped with a lot of new features and improvements. The Webpack team is close to having a complete migration and additions guide to Webpack 4. In the upcoming weeks and months, they'll be out. New to Webpack? I wrote a gentle introduction to the module bundler. Sean Larkin also has some awesome Webpack courses on Webpack Academy.

Have you started working with Webpack 4 yet? What are your thoughts? Let me know in the comments section! 😊