Configuration Languages

Webpack accepts configuration files written in multiple programming and data languages, so you can author your config in whichever format suits your project — JavaScript, TypeScript, CoffeeScript, or a plain data file like JSON5, YAML or TOML.

defineConfig

5.108.0+

defineConfig is a helper exported from webpack that gives editors type-checking and autocomplete for your configuration without any extra type annotations. It is an identity function (a no-op at runtime that simply returns the config you pass in), so it works in plain JavaScript configs too.

webpack.config.js

const { defineConfig } = require("webpack");

module.exports = defineConfig({
  mode: "none",
});

It accepts every shape webpack-cli can load: a single configuration object, an array of configurations (multi-compiler), a function returning either of those, an array of such functions, or a Promise resolving to any of them.

const { defineConfig } = require("webpack");

module.exports = defineConfig((env, argv) => ({
  mode: argv.mode ?? "development",
  // ...
}));

TypeScript

To write the webpack configuration in TypeScript, you would first install the necessary dependencies, i.e., TypeScript and the relevant type definitions from the DefinitelyTyped project:

npm install --save-dev typescript ts-node @types/node
# and, if using webpack-dev-server < v4.7.0
npm install --save-dev @types/webpack-dev-server

and then proceed to write your configuration:

webpack.config.ts

import path from "node:path";
import { fileURLToPath } from "node:url";

import webpack from "webpack";
// in case you run into any typescript error when configuring `devServer`
import "webpack-dev-server";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const config: webpack.Configuration = {
  mode: "production",
  entry: "./foo.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "foo.bundle.js",
  },
};

export default config;

tsconfig.json

{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "bundler",

    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "isolatedModules": true,

    // Allows you to write `import ... from './file.ts';`
    "rewriteRelativeImportExtensions": true
  }
}

The above sample assumes version >= 2.7 or newer of TypeScript is used with the new esModuleInterop and allowSyntheticDefaultImports compiler options in your tsconfig.json file.

We support configuration in both CommonJS and ESM format.

Starting with v22.18.0 Node.js supports built-in type stripping, so the additional settings described below are only required for older versions.

To enable the transformation of non erasable TypeScript syntax, which requires JavaScript code generation, such as enum declarations, parameter properties use the flag --experimental-transform-types.

If you are using an older version of Node.js that does not support the typescript format, or want to set module in compilerOptions in tsconfig.json to commonjs there are three solutions to this issue:

  • Modify tsconfig.json.
  • Modify tsconfig.json and add settings for ts-node.
  • Install tsconfig-paths.

The first option is to open your tsconfig.json file and look for compilerOptions. Set target to "ES5" and module to "CommonJS" (or completely remove the module option).

The second option is to add settings for ts-node:

You can keep "module": "ESNext" for tsc, and if you use webpack, or another build tool, set an override for ts-node. ts-node config

{
  "compilerOptions": {
    "module": "ESNext"
  },
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    }
  }
}

The third option is to install the tsconfig-paths package:

npm install --save-dev tsconfig-paths

And create a separate TypeScript configuration specifically for your webpack configs:

tsconfig-for-webpack-config.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "esModuleInterop": true
  }
}

Then set the environment variable process.env.TS_NODE_PROJECT provided by tsconfig-paths like so:

package.json

{
  "scripts": {
    "build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack"
  }
}

CoffeeScript

Similarly, to use CoffeeScript, you would first install the necessary dependencies:

npm install --save-dev coffeescript

and then proceed to write your configuration:

webpack.config.coffee

import path from 'node:path'
import { fileURLToPath } from 'node:url'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import webpack from 'webpack'

__filename = fileURLToPath(import.meta.url)
__dirname = path.dirname(__filename)

config =
  mode: 'production'
  entry: './path/to/my/entry/file.js'
  output:
    path: path.resolve(__dirname, 'dist')
    filename: 'my-first-webpack.bundle.js'
  module:
    rules: [
      {
        test: /\.(js|jsx)$/
        use: 'babel-loader'
      }
    ]
  plugins: [
    new HtmlWebpackPlugin(template: './src/index.html')
  ]

export default config

Babel and JSX

In the example below JSX (React JavaScript Markup) and Babel are used, to create a JSON configuration that webpack can understand.

Courtesy of Jason Miller

First, install the necessary dependencies:

npm install --save-dev babel-register jsxobj babel-preset-es2015

.babelrc

{
  "presets": ["es2015"]
}

webpack.config.babel.js

import jsxobj from "jsxobj";

// example of an imported plugin
const CustomPlugin = (config) => ({
  ...config,
  name: "custom-plugin",
});

export default (
  <webpack target="web" watch mode="production">
    <entry path="src/index.js" />
    <resolve>
      <alias
        {...{
          react: "preact-compat",
          "react-dom": "preact-compat",
        }}
      />
    </resolve>
    <plugins>
      <CustomPlugin foo="bar" />
    </plugins>
  </webpack>
);

Data formats (JSON5, YAML and TOML)

webpack-cli v7.1.0+

When your configuration is purely static data — no functions, no process.env reads, no computed values — you can write it as a data file instead of JavaScript. webpack-cli parses the following extensions directly:

ExtensionParser package
.json5json5
.yaml, .ymljs-yaml
.tomltoml

The parser is not bundled with webpack-cli — install the one your format needs as a dev dependency. If it is missing, webpack-cli stops and tells you exactly which package to install.

npm install --save-dev json5
# or
npm install --save-dev js-yaml
# or
npm install --save-dev toml

Point --config at the file, or name it so it is picked up as a default config (e.g. webpack.config.json5):

npx webpack --config webpack.config.toml

webpack.config.json5

{
  // JSON5 allows comments, unquoted keys and trailing commas
  mode: "production",
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
  },
}

webpack.config.yaml

mode: production
entry: ./src/index.js
output:
  filename: bundle.js

webpack.config.toml

mode = "production"
entry = "./src/index.js"

[output]
filename = "bundle.js"
Edit this page·

13 Contributors

piousonsokraskipjacktarang9211simon04peterblazejewiczyouta1119byzykNek-liyiming22daimalouChocolateLoverRajsnitin315