← Back to all tutorials

The webpack.config File

Create and understand the webpack.config.js file — configure entry points, output settings, mode, and dev server for full control over the build process.

The webpack.config File

While Webpack works with zero configuration, real projects need more control. The webpack.config.js file is where you define entry points, output settings, loaders, and plugins. In this episode you will create a config file and understand each section.

Creating webpack.config.js

Create a file called webpack.config.js in the project root:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};

This is the minimal config file. Webpack automatically looks for webpack.config.js in the project root when you run it.

Understanding Each Property

PropertyPurposeValue
modeSets the build environment'development' or 'production'
entryThe starting point filePath to your main JS file
output.filenameName of the output bundleAny filename (e.g., 'bundle.js')
output.pathDirectory for the outputMust be an absolute path

Why path.resolve?

path.resolve(__dirname, 'dist')
// On Windows: C:\Users\you\project\dist
// On Mac/Linux: /Users/you/project/dist

Webpack requires an absolute path for the output directory. path.resolve() creates an absolute path from the current directory (__dirname) and the relative folder name. This ensures the config works on any operating system.

Multiple Entry Points

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js',
        admin: './src/admin.js',
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};

For multi-page applications, you can define multiple entry points. The [name] placeholder in the filename is replaced with the entry point name — producing main.bundle.js and admin.bundle.js.

Output Placeholders

PlaceholderValueExample Output
[name]Entry point namemain.bundle.js
[contenthash]Hash based on file contentmain.a1b2c3d4.js
[id]Chunk ID0.bundle.js

The [contenthash] placeholder is especially useful for cache busting — the filename changes only when the content changes, so browsers cache unchanged files indefinitely.

Source Maps

module.exports = {
    mode: 'development',
    devtool: 'source-map',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};

The devtool property controls source map generation. Source maps let you debug the original source code in browser DevTools instead of the bundled output.

ValueQualitySpeedUse Case
'source-map'Best qualitySlowest buildProduction debugging
'eval-source-map'Good qualityFaster rebuildDevelopment
'cheap-module-source-map'Lines onlyFastDevelopment (less detail)
falseNo source mapsFastestProduction

Dev Server

npm install webpack-dev-server --save-dev

Add the dev server configuration:

module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    devServer: {
        static: {
            directory: path.resolve(__dirname, 'dist'),
        },
        port: 3000,
        open: true,
        hot: true,
    },
};
OptionPurpose
static.directoryFolder to serve static files from (HTML, images)
portPort number for the dev server
openAutomatically open the browser on start
hotEnable Hot Module Replacement (live updates without full reload)

Running the Dev Server

{
    "scripts": {
        "build": "webpack",
        "dev": "webpack serve"
    }
}
npm run dev

The dev server serves your files from memory (not disk), watches for changes, and automatically refreshes the browser. With Hot Module Replacement (HMR), CSS changes apply instantly without a full page reload.

The Module Rules Section

module.exports = {
    // ... entry, output, mode ...

    module: {
        rules: [
            // Loaders go here (next episodes)
        ],
    },
};

The module.rules array is where you define loaders. Each rule tells Webpack how to handle a specific file type. You will add Babel, CSS, and SASS loaders in the upcoming episodes.

Complete Config So Far

const path = require('path');

module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    devServer: {
        static: {
            directory: path.resolve(__dirname, 'dist'),
        },
        port: 3000,
        open: true,
        hot: true,
    },
    module: {
        rules: [],
    },
};

Key Takeaways

  • webpack.config.js is a Node.js module that exports a configuration object
  • The entry property defines where Webpack starts building the dependency graph
  • The output.path must be an absolute path — use path.resolve(__dirname, 'dist')
  • [name] and [contenthash] placeholders in filenames enable multi-entry builds and cache busting
  • devtool controls source map quality and build speed
  • webpack-dev-server provides live reloading and Hot Module Replacement during development
  • The module.rules array is where loaders are configured — covered in the next episodes