This article is part of the Webpack from Zero to Hero series, for more background or for the index, check the “Chapter 0: History”.

Previous - Chapter 1: Getting Started with the Basics

Next - Chapter 3: Everything is a Module

Introduction

Last chapter we saw the need for BabelJS to transpile our code, and the way to make Webpack pass files to other parsers like BabelJS, which is through loaders. But until now, we were running Webpack with no configuration file. In this chapter we’re going to create our very first Webpack configuration, learn how to use a loader and set up our local development server. Let’s start!

Chotto matte kudasai Marie Sensei, let’s keep our Webpack configuration clean from the start!

Babel requirements

First we need to install the dependencies:

yarn add @babel/core @babel/preset-env babel-loader --dev

Babel Core: it has all logic necessary for transformations and also some polyfills;

Babel Preset Env: it is able to choose the right transformations/polyfills depending on the target browser list;

Babel Loader: it will be responsible for receiving the input file from Webpack and passing it through BabelJS.

Configuration Files

Babel

First let’s setup the Babel to use the preset-env. Create a file called .babelrc with this content:

And set a browser list range on package.json:

Note: I’m creating a pretty generic query here. For production apps, always check analytics to properly choose your target browsers!

Let’s see how many browsers will be targeted with this query:

npx browserslist

As we don’t want to install browserslist just for a single run, we will directly use it through npx. The output will be (from the time of this article publication):

So one of the baselines for transpiling/polyfilling will probably be Internet Explorer 11 (and its mobile version). As I said before, don’t go for queries which are too generic, instead build the list based on usage data from your target audience.

Webpack

Now we just need to “tell Webpack” that all JS files should pass through Babel. Let’s create a webpack.config.js file on the project root directory and add this code:

Webpack config is just a NodeJS module, exporting the configuration object.

😖- “Hey, I don’t understand regular expressions, can you explain that?”

Right behind ya⚡️! The expression above should just match all files ending with .js:

We need to escape the “ . ” from .js , because in regex lingo it is used as a mask for “any character” and we don’t want it, we want the actual period char;

” from , because in regex lingo it is used as a mask for “any character” and we don’t want it, we want the actual period char; Then we set the “ $ ”, stating that the matching should end right after .js , so we don’t mismatch things like .json .

”, stating that the matching should end right after , so we don’t mismatch things like . Be happy, you’re a regex master now 💪 !

A Clean Config Sparks Joy ✨

Some will say to put all babel and browserslist configuration inside the Webpack configuration, but in my point of view, both Babel and browserslist configuration tend to stay the same (size-wise), while Webpack config tends to grow, so the key to keep it organized is to make it as modular as possible. Like with any normal source code (remember that the Webpack configuration is a Node.js file!), if you see it’s growing, assuming too many responsibilities and repeating the code, you should break it up!

Development Environment

For any app/site development, we need to create a dev environment, where we can test and see the updates right away. And since we haven’t seen our actual code running in the browser yet, I think is time already, let’s go and do it!

Webpack Development Server

As you may know or have heard about, Webpack has a pretty nice tool called webpack-dev-server, where you can simulate an HTTP server on your machine integrated with a hot module reloading feature. It is pretty nice as the browser reloads every time a compilation is triggered, and you don’t need to be reloading the page manually every time you do a change to your code.

Installation

We will install both the webpack dev server and the plugin to generate an index.html for us:

yarn add webpack-dev-server html-webpack-plugin --dev

Setup

On the webpack config we add the plugin to the “plugins” section:

Tip of the day: If you don’t want to output an index.html on the production builds, we can skip it by checking the webpack argv.mode:

Some explanation for the code above:

Webpack accepts both an Object or a Function as configuration. When you provide it as a function, it will inject the env and the argv as parameters:

env: everything the client (webpack-cli) receives under the env param comes as an env object property, e.g.:

--env.test or --env.customValue="Hello there!"

argv: all the arguments given to webpack config that are part of the configuration schema, e.g.:

--mode=production

As we’re starting simple there’s no need yet to create two configuration files, one for development and another for production, so let’s stick to simplicity.

Now is time to run the server, which accepts the same arguments that the webpack client does (plus some additional ones). Let’s remove the “build:dev” in package.json and change to:

Let’s test it!

yarn start:dev

And you’re going to see something like this: