6 ways to configure Webpack
Tags: javascript, typescript, webdev, beginners
Published: 2021-06-23 15:04:47

---
title: 6 ways to configure Webpack
published: true
description: 
tags: javascript, typescript, webdev, beginners
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9njibnh4d0ii8crbq08m.png
---
 
[Webpack](https://webpack.js.org/) is a build tool to make code, which was not primarily written for execution in browsers, executable in web browsers. With special plugins, webpack can manage many types of code, for example JavaScript, TypeScript, and Rust-generated WebAssembly.

There are webpack plugins to also compile, minify, shim, chunk, and bundle code. However, webpack was not designed to execute tasks such as linting, building, or testing your app. For this purpose, there are task runners such as [Grunt](https://gruntjs.com/), [Gulp](https://gulpjs.com/) or [npx](https://docs.npmjs.com/cli/v7/commands/npx).

In order to manage the functionality of webpack, it must be configured. Here are six different ways, in which webpack's configuration can be written.

## 1. Zero Config

As of webpack version 4, you are not required to specify a configuration. By default, webpack assumes that your code starts at `src/index.js` and will be bundled to `dist/main.js`. This is very convenient and promotes [convention over configuration](https://en.wikipedia.org/wiki/Convention_over_configuration) but it does not use webpack's full potential.

Without a configuration, webpack does not know whether code should be compressed for faster execution or bundled with source maps for better tracking of errors. Webpack expresses its confusion with the following warning:

> WARNING in configuration
>
> The 'mode' option has not been set, webpack will fallback to 'production' for this value.
>
> Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
>
> You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

Let's have a look at options to tell webpack how it should be configured.

## 2. Command Line Interface

To see all available commands and options to configure webpack from the command line interface, you can run `webpack --help`. This command will show you a list of arguments and how to use them. The following execution mimics the default (zero config) behaviour of webpack:

```bash
webpack --entry=./src/index.js --output-path=./dist --output-filename=main.js
```

As you can see, CLI configurations can become quite long. In order to minimize the writing effort, there is also a shorthand version of the above command:

```bash
webpack ./src/index.js -o ./dist
```

The simplified notation is at the expense of comprehensibility, which is why we will look at configuration files in the next step.

## 3. CommonJS Configuration File

Webpack can be instructed to read in a configuration file. By default, a file named `webpack.config.js` is being used. You can create it by using the `npx webpack init` command or by writing it yourself:

**webpack.config.js**

```js
const path = require("path");

const config = {
  entry: "./src/index.js",
  mode: "development",
  module: {
    rules: [
      {
        exclude: /(node_modules)/,
        test: /\.(js|jsx)$/i,
        loader: "babel-loader"
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, "dist")
  },
  plugins: []
};

module.exports = config;
```

The configuration uses the CommonJS module syntax with `require` and `module.exports`. Make sure that your `package.json` does not define `"type": "module"`, otherwise you will receive the following error:

> [webpack-cli] ReferenceError: require is not defined

The configuration file should also be in the root of your project.

## 4. ESM Configuration File

If your `package.json` file specifies `"type": "module"` and you want to make use of ECMAScript modules, then you can also modernize your webpack configuration:

**webpack.config.js**

```js
import path from "path";

const config = {
  entry: "./src/index.js",
  mode: "development",
  module: {
    rules: [
      {
        exclude: /(node_modules)/,
        test: /\.(js|jsx)$/i,
        loader: "babel-loader"
      }
    ]
  },
  output: {
    path: path.resolve("./dist")
  },
  plugins: []
};

export default config;
```

## 5. TypeScript Configuration File

For those of you who like to work with TypeScript, webpack offers the possibility to use a configuration file written in TypeScript. 

Webpack v5 already ships with TypeScript definitions, so you don't have to install [@types/webpack](https://www.npmjs.com/package/@types/webpack) but you need to install [typescript](https://www.npmjs.com/package/typescript), [ts-node](https://www.npmjs.com/package/ts-node) and [@types/node](https://www.npmjs.com/package/@types/node).

Because the extension `.ts` does not correspond to the standard `.js` extension, webpack has to be informed about this via the `--config` argument:

```bash
webpack --config webpack.config.ts
```

You also have to make sure that the test patterns of your "rules" and your "resolve" definitions include the TypeScript extension:

**webpack.config.ts**

```ts
import path from "path";
import { Configuration } from "webpack";

const config: Configuration = {
  entry: "./src/index.js",
  mode: "development",
  module: {
    rules: [
      {
        exclude: /(node_modules)/,
        test: /\.[tj]sx?$/,
        loader: "babel-loader"
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, "./dist")
  },
  plugins: [],
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx"]
  }
};

export default config;
```

☝️ Because the exemplary webpack configuration loads [Babel](https://babeljs.io/), we can still point to a JavaScript entry file as Babel makes it possible to use JavaScript and TypeScript code simultaneously.

⚠️ Please note that TypeScript configuration files cannot be used with ESM (see [ESM in webpack.config.ts isn't supported](https://github.com/webpack/webpack-cli/issues/2458)).

## 6. Node Interface

In addition to the execution via `webpack-cli`, webpack also supports a programmatic interface. This allows you to compile your frontend code on a Node.js server. Here is an example:

```ts
import express from "express";
import { webpack } from "webpack";
import webpackConfig, { webappDir } from "../webpack.config.js";

export function useWebpack(app: express.Express) {
  const webpackCompiler = webpack(webpackConfig);
  const webpackDevMiddleware = require("webpack-dev-middleware");
  const webpackHotMiddleware = require("webpack-hot-middleware");

  app.use(webpackDevMiddleware(webpackCompiler));
  app.use(webpackHotMiddleware(webpackCompiler));

  app.use(express.static(webappDir));
}
```

Instead of consuming your existing `webpack.config.js` file, you can also pass a configuration object to the `webpack` API.

## Get connected 🔗

Please [follow me on Twitter](https://twitter.com/bennycode) or [subscribe to my YouTube channel](https://www.youtube.com/c/typescripttv) if you liked this post. I would love to hear from you what you are building. 🙂 Best, Benny