Skip to content
All essays
CraftMarch 25, 202418 min

Webpack Complete Guide

Master Webpack from basics to advanced: configuration, loaders, plugins, optimization, and best practices

Ü
Ümit Uz
Mobile & Full Stack Developer

Webpack is the most popular module bundler for JavaScript applications. Let's master it from configuration to optimization.

What is Webpack?

Webpack takes modules with dependencies and generates static assets representing those modules. It's a powerful tool that:

  • Bundles JavaScript modules
  • Transforms assets ( Sass, TypeScript, JSX)
  • Optimizes output for production
  • Enables hot module replacement

Core Concepts

Entry

The entry point is the module Webpack looks for to start building your bundle.

javascript
// webpack.config.js
module.exports = {
  entry: './src/index.js'
};

Multiple entry points:

javascript
module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js'
  }
};

Output

Where Webpack emits the bundles:

javascript
const path = require('path');

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

Loaders

Loaders transform files before they're added to the bundle.

javascript
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: ['file-loader']
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  }
};

Plugins

Plugins perform tasks that loaders can't.

javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css'
    })
  ]
};

Configuration Modes

javascript
module.exports = {
  mode: 'production', // or 'development' or 'none'
  // Production mode enables optimizations automatically
};

Development Setup

Dev Server

bash
npm install webpack-dev-server --save-dev
javascript
module.exports = {
  devServer: {
    contentBase: './dist',
    hot: true,
    port: 3000,
    open: true
  }
};

Source Maps

javascript
module.exports = {
  devtool: 'inline-source-map' // Development
  // For production: 'source-map' or false
};

Production Optimization

Code Splitting

javascript
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendors: {
          test: /\/[\\/]node_modules[\\/]/,
          priority: -10
        }
      }
    }
  }
};

Minification

javascript
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()]
  }
};

Tree Shaking

javascript
module.exports = {
  optimization: {
    usedExports: true,
    sideEffects: false
  }
};

Caching

javascript
module.exports = {
  output: {
    filename: '[name].[contenthash].js'
  },
  optimization: {
    runtimeChunk: 'single',
    moduleIds: 'deterministic'
  }
};

Advanced Loaders

Babel Loader

javascript
module.exports = {
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
};

CSS/SASS Loader

javascript
module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  }
};

Image Loader

javascript
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024 // 8kb
          }
        }
      }
    ]
  }
};

Performance Optimization

Bundle Analysis

bash
npm install webpack-bundle-analyzer --save-dev
javascript
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
};

Lazy Loading

javascript
// Dynamic import
const module = await import('./module');

Prefetching/Preloading

javascript
import(/* webpackPrefetch: true */ './path/to/LoginModal.js');

Common Configurations

React App

javascript
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx']
  }
};

TypeScript App

javascript
module.exports = {
  entry: './src/index.ts',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  }
};

Troubleshooting

Common Issues

  1. 1Slow build: Check for large node_modules, use cache
  2. 2Large bundles: Enable code splitting, tree shaking
  3. 3Missing files: Check resolve.extensions
  4. 4Loader errors: Verify test patterns and loader order

Debug Mode

javascript
module.exports = {
  stats: {
    colors: true,
    modules: true,
    reasons: true
  }
};

Migration Tips

From Webpack 4 to 5:

  • Remove deprecated plugins (CleanWebpackPlugin built-in)
  • Update loaders to latest versions
  • Use asset modules instead of file-loader/url-loader
  • Update Node.js polyfills if needed

Conclusion

Webpack is complex but powerful. Start with basic configuration, add features as needed, and always measure bundle size and build performance. The official documentation and webpack-merge for managing multiple configs are your friends.

Related essays

Next essay
Web Security Best Practices