Webpack 4 Tutorial: from 0 Conf to Production Mode

The webpack team is working hard on the next generation of the popular module bundler: webpack 4.

webpack 4 logo

The following post is a living, breathing introduction to webpack 4. I’ll update it as soon as new info will come in.

webpack 4 as a zero configuration module bundler

webpack is powerful and has a lot of unique features but one of its pain point is the configuration file.

Providing a configuration for webpack is not a big deal in medium to bigger projects. You can’t live without one. Yet, for smaller ones it’s kind of annoying, especially when you want to kickstart some toy app.

That’s why Parcel gained a lot of traction.

Sean and the webpack team are going to change that: webpack 4 doesn’t need a configuration file by default!

Let’s try that out.

Create a new directory and move into it:

mkdir webpack-4-quickstart && cd $_

Initialize a package.json by running:

npm init -y

Now let’s pull webpack 4 in.

webpack 4 is in beta. That means we should get it from the next branch:

npm i webpack@next --save-dev

We need webpack-cli also, which lives as a separate package:

npm i webpack-cli --save-dev

Now open up package.json and add a build script:

"scripts": {
  "build": "webpack"
}

Close the file and save it.

Try to run:

npm run build

and see what happens:

ERROR in Entry module not found: Error: Can't resolve './src' in '~/webpack-4-quickstart'

webpack 4 is looking for an entry point in ./src! If you don’t know what that means go check out my previous article on switching from Gulp to webpack.

In brief: the entry point is the file webpack looks for to start building your Javascript bundle.

In the previous version of webpack the entry point has to be defined inside a configuration file named webpack.config.js.

But starting from webpack 4 there is no need to define the entry point: it will take ./src/index.js as the default!

Testing the new feature is easy. Create ./src/index.js:

console.log(`I'm a silly antry point`);

and run the build again:

npm run build

You will get the bundle in ~/webpack-4-quickstart/dist/main.js.

What? Wait a moment. There is no need to define the output file? Exactly.

In webpack 4 there is no need to define neither the entry point, nor the output file.

I know that for a lot of people that’s not so exciting. Webpack’s main strength is code splitting. But trust me, having a zero configuration tool speeds things up.

So here is the first news: webpack 4 doesn’t need a configuration file.

It will look in ./src/index.js as the default entry point. Moreover, it will spit out the bundle in ./dist/main.js.

In the next section we’ll see another nice feature of webpack 4: production and development mode.

webpack 4: production and development mode

Having 2 configuration files is a common pattern in webpack.

A tipical project may have:

  • a configuration file for development, for defining webpack dev server and other stuff
  • a configuration file for production, for defining UglifyJSPlugin, sourcemaps and so on

While bigger projects may still need 2 files, in webpack 4 you can get by without a single line of configuration.

How so?

webpack 4 introduces production and development mode.

In fact if you pay attention at the output of npm run buildyou’ll see a nice warning:

webpack 4 development and production mode

The ‘mode’ option has not been set. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for this environment.

What does that mean? Let’s see.

Open up package.json and fill the script section like the following:

"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}

Now try to run:

npm run dev

and take a look at ./dist/main.js. What do you see? Yes, I know, a boring bundle… not minified!

Now try to run:

npm run build

and take a look at ./dist/main.js. What do you see now? A minified bundle!

Yes!

Production mode enables all sorts of optimizations out of the box. Including minification, scope hoisting, tree-shaking and more.

Development mode on the other hand is optimized for speed and does nothing more than providing an un-minified bundle.

So here is the second news: webpack 4 introduces **production** and **development** mode.

In webpack 4 you can get by without a single line of configuration! Just define the --modeflag and you get everything for free!

webpack 4: transpiling Javascript ES6 with Babel

webpack 4: transpiling Javascript ES6 with Babel

Modern Javascript is mostly written in ES6.

But not every browser know how to deal with ES6. We need some kind of transformation.

This transformation step is called transpiling. Transpiling is the act of taking ES6 and making it understandable by older browsers.

Webpack doesn’t know how to make the transformation but has loaders: think of them as of transformers.

babel-loader is the webpack loader for transpiling ES6 and above, down to ES5.

To start using the loader we need to install a bunch of dependencies. In particular:

  • babel-core
  • babel-loader
  • babel-preset-env for compiling Javascript ES6 code down to ES5

Let’s do it:

npm i babel-core babel-loader babel-preset-env --save-dev

Next up configure Babel by creating a new file named .babelrc inside the project folder:

{
    "presets": [
        "env"
    ]
}

At this point we have 2 options for configuring babel-loader:

  • using a configuration file for webpack
  • using --module-bindin your npm scripts

Yes, I know what you’re thinking. webpack 4 markets itself as a zero configuration tool. Why would you write a configuration file again?

The concept of zero configuration in webpack 4 applies to:

  • the entry point. Default to ./src/index.js
  • the output. Default to ./dist/main.js
  • production and development mode (no need to create 2 separate confs for production and development)

And it’s enough. But for using loaders in webpack 4 you still have to create a configuration file.

I’ve asked Sean about this. Will loaders in webpack 4 work the same as webpack 3? Is there any plan to provide 0 conf for common loaders like babel-loader?

His response:

“For the future (after v4, maybe 4.x or 5.0), we have already started the exploration of how a preset or addon system will help define this. What we don’t want: To try and shove a bunch of things into core as defaults What we do want: Allow other to extend”

For now you must still rely on webpack.config.js. Let’s take a look…

webpack 4: using babel-loader with a configuration file

Give webpack a configuration file for using babel-loader in the most classical way.

Create a new file named webpack.config.jsand configure the loader:

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};

There is no need to specify the entry point unless you want to customize it.

Next up open ./src/index.js and write some ES6:

const arr = [1, 2, 3];
const iAmJavascriptES6 = () => console.log(...arr);
window.iAmJavascriptES6 = iAmJavascriptES6;

Finally create the bundle with:

npm run build

Now take a look at ./dist/main.js to see the transpiled code.

webpack 4: using babel-loader without a configuration file

There is another method for using webpack loaders.

The --module-bindflag let’s you specify loaders from the command line. Thank you Cezar for pointing this out.

The flag is not webpack 4 specific. It was there since version 3.

To use babel-loader without a configuration file configure your npm scripts in package.json like so:

"scripts": {
    "dev": "webpack --mode development --module-bind js=babel-loader",
    "build": "webpack --mode production --module-bind js=babel-loader"
  }

And you’re ready to run the build.

I’m not a fan of this method (I don’t like fat npm scripts) but it is interesting nonetheless.

Stay tuned! More coming soon…

This is a living, breathing **introduction to webpack 4**. Stay tuned for more!

webpack 4: resources

A Github repo for the tutorial => webpack-4-quickstart

I know there’s already an awesome webpack list but here’s mine: a list of awesome resources about webpack 4 => awesome-webpack-4

Valentino Gagliardi

Valentino Gagliardi

Web Developer & IT Consultant, with over 10 year of experience, I'm here to help you developing your next idea.
Valentino Gagliardi

4 Replies to “Webpack 4 Tutorial: from 0 Conf to Production Mode”

  1. Could you please explain how to configure loaders in Webpack 4? (react)
    This is webpack.config.js from webpack 3 (but is no longer allowed):
    module: {
    loaders: [
    {
    test: /\.jsx?/,
    include: APP_DIR,
    loader: “babel-loader”
    }
    ]
    }

  2. @rune add this to the script: `–module-bind js=babel-loader` as in:
    `”dev”: “webpack –mode development –module-bind js=babel-loader”`

Leave a Reply

Your email address will not be published. Required fields are marked *