Webpack 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, Gulp or 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 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:
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:
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
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
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 but you need to install typescript, ts-node and @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:
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
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, 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).
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:
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 or subscribe to my YouTube channel if you liked this post. I would love to hear from you what you are building. π Best, Benny
Top comments (5)
Nice!
Thanks for the post! Very cool things that I didn't know wow βΊοΈ
Grt π₯
Use webpack-builder-config from npm
@vitaliyirtlach can it be used to create a template that can be loaded by "@webpack-cli/generators"?