SkillByAIOpen interactive version →

Lesson 25 / 25

Real-world applications and best practices

Assemble a production-ready Webpack configuration with minification, hashing, code splitting and performance budgets.

Production-ready configuration

A production Webpack config should minify bundles, enable source maps for debugging, separate vendor and application code, use code splitting, use contenthash for caching, set performance budgets, and validate builds in CI.

Production configuration template

A comprehensive production-ready Webpack configuration.

const HtmlPlugin = require('html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const path = require('path');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true
  },
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()],
    runtimeChunk: 'single',
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: 10
        }
      }
    }
  },
  plugins: [
    new HtmlPlugin({ template: './src/index.html' })
  ]
};

Output:

Ready for production deployment with optimal caching and performance

Continuous improvement

Monitor bundle sizes, build times, and runtime performance in production. Set performance budgets. Use error tracking and performance monitoring tools. Regularly audit dependencies for vulnerabilities. Plan migrations to newer tools as the ecosystem evolves. Document your configuration for team members.

Complete project setup

See a fully configured project ready for production deployment.

npm init -y
npm install --save-dev webpack webpack-cli webpack-dev-server
npm install --save-dev html-webpack-plugin mini-css-extract-plugin
npm install --save-dev babel-loader @babel/core @babel/preset-env
npm run build
# Result: optimized bundles in dist/ with cache-busting hashes

Output:

asset main.[contenthash].js 45.2 KiB [compared for emit]
asset vendors.[contenthash].js 12.1 KiB
asset index.html 0.5 KiB

Quick check

Quick check: What makes a configuration production-ready?

  • Using the largest bundle size.
  • Minification, sourcemaps, caching, and code splitting.
  • Disabling all optimizations.
  • Hard-coded absolute paths and no hashing.
Answer

Minification, sourcemaps, caching, and code splitting. — Production-ready configs optimize for performance, caching, debugging, and reliability through minification, code splitting, and proper sourcemaps.

Final quiz 1 of 8

Final quiz

Quick check: Which option tells Webpack where to start building the dependency graph?

  • output
  • entry
  • resolve
  • devtool
Answer

entry — The entry point is the root from which Webpack follows imports.

Final quiz 2 of 8

Final quiz

Quick check: Which loader order correctly processes CSS in a rule's use array?

  • ['css-loader', 'style-loader']
  • ['style-loader', 'css-loader']
  • ['css-loader'] only
  • ['babel-loader', 'style-loader']
Answer

['style-loader', 'css-loader'] — Loaders run right to left, so css-loader parses first and style-loader injects the result.

Final quiz 3 of 8

Final quiz

Quick check: What is the main difference between a loader and a plugin?

  • Loaders hook into the whole build lifecycle; plugins transform single files.
  • Loaders transform individual files; plugins hook into the build lifecycle.
  • Plugins run only in development.
  • There is no difference.
Answer

Loaders transform individual files; plugins hook into the build lifecycle. — Loaders work per file type; plugins handle broader build tasks.

Final quiz 4 of 8

Final quiz

Quick check: Which technique removes unused exports from a production bundle?

  • Tree-shaking
  • Hot module replacement
  • Source mapping
  • Aliasing
Answer

Tree-shaking — Tree-shaking relies on static ES module imports to drop dead code.

Final quiz 5 of 8

Final quiz

Quick check: How do you load a heavy module only when the user needs it?

  • Use a dynamic import()
  • Use a static import at the top
  • Set mode to development
  • Rename the entry file
Answer

Use a dynamic import() — Dynamic import() creates a separate chunk that loads on demand.

Final quiz 6 of 8

Final quiz

Quick check: Why use [contenthash] in output filenames?

  • It encrypts the bundle.
  • It changes only when content changes, enabling long-term caching.
  • It speeds up the dev server.
  • It enables source maps.
Answer

It changes only when content changes, enabling long-term caching. — An unchanged file keeps its name, so browsers reuse the cached copy.

Final quiz 7 of 8

Final quiz

Quick check: What does HMR do in webpack-dev-server?

  • Minifies code on save.
  • Replaces changed modules without a full page reload.
  • Uploads source maps to production.
  • Splits vendor chunks.
Answer

Replaces changed modules without a full page reload. — HMR swaps updated modules in place and preserves application state.

Final quiz 8 of 8

Final quiz

Quick check: Which tool helps you find what is making a bundle large?

  • webpack-bundle-analyzer
  • html-webpack-plugin
  • css-loader
  • fork-ts-checker-webpack-plugin
Answer

webpack-bundle-analyzer — The analyzer visualises bundle composition so large dependencies stand out.