Webpack 5 & Modern Build Tools Cheatsheet
Table of Contentsโ
- Build Tools Overview
- Why Build Tools Are Needed
- Webpack 5
- Vite
- Why Vite is Faster
- Other Modern Build Tools
- Performance Comparison
- When to Use What
- Migration Guide
- Interview Questions
Build Tools Overviewโ
What Are Build Tools?โ
Build tools transform and bundle source code into optimized production assets.
Source Code Build Tool Production
โโโ TypeScript โ โ โโโ Minified JS
โโโ JSX/TSX โ Webpack/Vite โ โโโ CSS bundles
โโโ SASS/LESS โ โ โโโ Optimized images
โโโ Modern JS โ โ โโโ index.html
โโโ Assets
Popular Build Toolsโ
| Tool | Type | Release | Primary Use Case |
|---|---|---|---|
| Webpack | Bundler | 2012 | Production apps, complex configs |
| Vite | Dev Server + Bundler | 2020 | Fast dev, modern projects |
| Rollup | Bundler | 2015 | Libraries, tree-shaking |
| Parcel | Zero-config bundler | 2017 | Quick prototypes |
| esbuild | Bundler | 2020 | Extremely fast builds |
| Turbopack | Bundler | 2022 | Next.js, Rust-based |
| SWC | Compiler | 2020 | Faster Babel alternative |
Why Build Tools Are Neededโ
Key Problems They Solveโ
1. Module Systemโ
Browsers don't natively support CommonJS/ES Modules everywhere.
// Won't work directly in older browsers
import React from 'react';
const lodash = require('lodash');
2. Code Transformationโ
Transform modern syntax to browser-compatible code.
// JSX โ JavaScript
<div className="app">Hello</div>
// โ
React.createElement('div', { className: 'app' }, 'Hello')
3. Asset Processingโ
Handle CSS, images, fonts, etc.
import './styles.css';
import logo from './logo.png';
4. Code Optimizationโ
- Minification
- Tree shaking (remove unused code)
- Code splitting
- Dead code elimination
5. Developer Experienceโ
- Hot Module Replacement (HMR)
- Source maps
- TypeScript support
- Fast refresh
Webpack 5โ
Core Conceptsโ
// webpack.config.js
module.exports = {
// 1. Entry: Starting point
entry: './src/index.js',
// 2. Output: Where to emit bundles
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
},
// 3. Loaders: Transform files
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif)$/,
type: 'asset/resource',
},
],
},
// 4. Plugins: Additional functionality
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new MiniCssExtractPlugin(),
],
// 5. Mode: development or production
mode: 'production',
};
How Webpack Worksโ
1. Entry Point
โ
2. Build Dependency Graph (parse all imports)
โ
3. Apply Loaders (transform files)
โ
4. Apply Plugins (optimize, emit assets)
โ
5. Output Bundle(s)
Webpack 5 Key Featuresโ
1. Persistent Cachingโ
module.exports = {
cache: {
type: 'filesystem', // Cache to disk
buildDependencies: {
config: [__filename],
},
},
};
2. Module Federationโ
Share code between separate builds (microfrontends).
// App 1 (host)
new ModuleFederationPlugin({
name: 'host',
remotes: {
app2: 'app2@http://localhost:3002/remoteEntry.js',
},
});
// App 2 (remote)
new ModuleFederationPlugin({
name: 'app2',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/Button',
},
});
// Use in App 1
import Button from 'app2/Button';
3. Asset Modulesโ
No need for file-loader, url-loader, raw-loader.
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource', // Emits separate file
},
{
test: /\.svg$/,
type: 'asset/inline', // Inline as data URI
},
{
test: /\.txt$/,
type: 'asset/source', // Export as string
},
{
test: /\.jpg$/,
type: 'asset', // Auto choose based on size
parser: {
dataUrlCondition: {
maxSize: 8 * 1024, // 8kb
},
},
},
],
},
};
4. Tree Shaking Improvementsโ
Better detection of unused exports.
// utils.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b; // Won't be bundled if unused
// app.js
import { add } from './utils';
console.log(add(2, 3));
5. Code Splittingโ
// Dynamic imports
const loadComponent = async () => {
const module = await import(/* webpackChunkName: "heavy" */ './HeavyComponent');
return module.default;
};
// Split vendors
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10,
},
},
},
}
Webpack Dev Serverโ
devServer: {
port: 3000,
hot: true, // Hot Module Replacement
open: true,
historyApiFallback: true, // SPA routing
proxy: {
'/api': 'http://localhost:8080',
},
}
Viteโ
What is Vite?โ
Fast dev server + production bundler (uses Rollup) built on native ES modules.
Basic Setupโ
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
},
build: {
outDir: 'dist',
sourcemap: true,
},
});
How Vite Worksโ
Development Modeโ
Browser Request
โ
Vite Dev Server
โ
Transform on-demand (esbuild)
โ
Serve ES Modules
Key Difference: No bundling in dev! Each file is served separately.
<!-- Vite serves this directly -->
<script type="module">
import { createApp } from '/node_modules/vue/dist/vue.esm-browser.js'
import App from '/src/App.vue'
createApp(App).mount('#app')
</script>
Production Modeโ
Uses Rollup for optimized bundling.
Source Files
โ
Rollup (bundler)
โ
Optimized Bundle
Vite Featuresโ
1. Instant Server Startโ
# Webpack: 10-30s for large projects
npm run webpack-dev
# Vite: <1s regardless of project size
npm run vite
2. Lightning Fast HMRโ
// Vite only updates the changed module
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
// Handle update
});
}
3. Optimized Dependenciesโ
Vite pre-bundles dependencies with esbuild.
node_modules/
โโโ react (100+ files)
โโโ lodash (500+ files)
โ (Pre-bundled)
.vite/deps/
โโโ react.js (1 file)
โโโ lodash.js (1 file)
4. Built-in Featuresโ
No loaders needed for common files:
// TypeScript
import Component from './Component.tsx';
// CSS
import './styles.css';
// CSS Modules
import styles from './App.module.css';
// JSON
import data from './data.json';
// Assets
import logo from './logo.png';
// Web Workers
import Worker from './worker?worker';
5. Environment Variablesโ
// .env
VITE_API_URL=https://api.example.com
// Access in code
console.log(import.meta.env.VITE_API_URL);
Why Vite is Fasterโ
1. No Bundling in Developmentโ
Webpack Dev:
[All Files] โ Bundle โ Serve (slow start)
Vite Dev:
[Request] โ Transform Single File โ Serve (instant)
2. Native ES Modulesโ
Modern browsers support ES modules natively.
// Browser can handle this directly
import { useState } from 'react';
3. esbuild for Dependenciesโ
esbuild is written in Go (10-100x faster than JavaScript-based tools).
Babel Transform: ~1000ms
esbuild Transform: ~10ms
4. Smart Dependency Pre-bundlingโ
// These are pre-bundled once
import _ from 'lodash'; // 100s of files โ 1 file
import React from 'react'; // Multiple files โ 1 file
// These are transformed on-demand
import App from './App.jsx'; // Your code
5. Optimized HMRโ
Webpack HMR:
Change โ Rebuild affected chunks โ Full page update
Vite HMR:
Change โ Transform single module โ Precise update
6. Better Cachingโ
// Strong caching with immutable filenames
// dist/assets/index-4f3b8d2a.js
// โ Change code
// dist/assets/index-8a2c9f1b.js (new hash)
Performance Numbersโ
Cold Server Start:
Webpack: 15-30s (large project)
Vite: <1s
Hot Module Replacement:
Webpack: 200-500ms
Vite: <50ms
Production Build:
Webpack: 30-60s
Vite: 20-40s (uses Rollup)
Other Modern Build Toolsโ
esbuildโ
Extremely fast bundler written in Go.
// esbuild.config.js
require('esbuild').build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
minify: true,
});
Speed: 10-100x faster than webpack Limitation: Less plugin ecosystem
Turbopack (Next.js)โ
Rust-based bundler by Vercel.
// next.config.js
module.exports = {
experimental: {
turbo: {}, // Enable Turbopack
},
};
Claims: 700x faster than Webpack, 10x faster than Vite (disputed)
Rollupโ
Tree-shaking focused bundler, great for libraries.
// rollup.config.js
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm',
},
plugins: [resolve(), commonjs(), terser()],
};
Parcelโ
Zero-config bundler.
# No config needed
parcel index.html
Pros: Easy to use Cons: Less control, slower than modern tools
SWCโ
Rust-based JavaScript/TypeScript compiler (Babel alternative).
// .swcrc
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}
Speed: 20x faster than Babel Used by: Next.js, Vite (optionally)
Performance Comparisonโ
Build Speed (10,000 modules)โ
Tool Cold Start Hot Reload Production Build
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Webpack 5 ~25s ~300ms ~45s
Vite <1s ~50ms ~30s
esbuild <500ms N/A ~5s
Turbopack ~1s ~30ms ~25s
Why Speed Differences?โ
Language Implementation:
JavaScript (Webpack): Slow
Go (esbuild): Fast (10-100x)
Rust (Turbopack, SWC): Fast (10-100x)
Architecture:
Bundle-first (Webpack): Slow dev start
Module-first (Vite): Fast dev start
When to Use Whatโ
Use Webpack When:โ
โ You need Module Federation โ Complex custom configurations required โ Legacy project migration โ Need specific loaders/plugins โ Team is already familiar with it
// Complex webpack use case
module.exports = {
entry: {
app: './src/app.js',
admin: './src/admin.js',
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
};
Use Vite When:โ
โ Starting a new project โ Developer experience is priority โ Modern browser targets โ TypeScript/JSX/CSS modules โ Fast iteration needed
// Simple Vite setup
export default defineConfig({
plugins: [react()],
// That's it for most projects!
});
Use esbuild When:โ
โ Building libraries โ CI/CD pipelines (speed critical) โ Simple bundling needs โ No complex transformations
Use Rollup When:โ
โ Building npm packages โ Tree-shaking is critical โ Multiple output formats needed
// Library with multiple formats
export default {
input: 'src/index.js',
output: [
{ file: 'dist/bundle.cjs.js', format: 'cjs' },
{ file: 'dist/bundle.esm.js', format: 'esm' },
{ file: 'dist/bundle.umd.js', format: 'umd', name: 'MyLib' },
],
};
Migration Guideโ
Webpack to Viteโ
// webpack.config.js
module.exports = {
entry: './src/main.js',
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.jsx?$/, use: 'babel-loader' },
],
},
};
// โ Migrate to โ
// vite.config.js
export default defineConfig({
plugins: [react()],
// CSS and JSX work out of the box!
});
Key Changesโ
// Webpack: CommonJS
const path = require('path');
module.exports = { /* ... */ };
// Vite: ES Modules
import { defineConfig } from 'vite';
export default defineConfig({ /* ... */ });
// Webpack: Environment variables
process.env.REACT_APP_API_URL
// Vite: Environment variables
import.meta.env.VITE_API_URL
// Webpack: Import assets
import logo from './logo.png';
// Vite: Import assets (same, but different handling)
import logo from './logo.png'; // Returns URL
import logo from './logo.png?url'; // Explicit URL
import logo from './logo.png?raw'; // Raw string
Migration Checklistโ
- Update
package.jsonscripts - Convert webpack config to vite config
- Update environment variable names (
REACT_APP_*โVITE_*) - Remove webpack-specific loaders
- Update import statements if using CommonJS
- Test all dynamic imports
- Update proxy configuration
- Test production build
Interview Questionsโ
1. What is tree shaking?โ
Removing unused code from bundles. Works with ES modules (static analysis).
// lib.js
export function used() { return 'used'; }
export function unused() { return 'unused'; }
// app.js
import { used } from './lib';
console.log(used());
// Bundle: Only includes 'used' function
2. What is code splitting?โ
Breaking code into separate bundles loaded on-demand.
// Static
import Component from './Component';
// Dynamic (creates separate chunk)
const Component = lazy(() => import('./Component'));
3. How does HMR work?โ
Hot Module Replacement updates modules without full page reload.
File Change โ Dev Server Detects โ WebSocket Message โ Update Module
4. Why is Vite faster than Webpack in development?โ
- No bundling (uses native ES modules)
- On-demand transformation (only requested files)
- esbuild for dependencies (Go vs JavaScript)
- Optimized dependency pre-bundling
- Better caching strategy
5. What is the difference between loader and plugin in Webpack?โ
Loaders: Transform individual files (CSS, TS, images) Plugins: Perform broader tasks (optimization, injection, bundling)
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' }, // Loader
],
},
plugins: [
new HtmlWebpackPlugin(), // Plugin
],
6. Explain Module Federationโ
Share code between separate Webpack builds at runtime.
// Use case: Microfrontends
// App A can import components from App B
// without rebuilding or duplicating code
7. What are source maps?โ
Map minified/transformed code back to original source for debugging.
devtool: 'source-map', // webpack
build: { sourcemap: true }, // vite
8. How does Vite handle dependencies?โ
Pre-bundles with esbuild, caches aggressively, serves as single files.
First run: Scan โ Pre-bundle โ Cache
Subsequent: Serve from cache (instant)
9. What is the purpose of content hashing?โ
Cache busting - new hash when content changes.
output: {
filename: '[name].[contenthash].js', // webpack
}
// Produces: main.4f3b8d2a.js
// Change content โ main.8a2c9f1b.js
10. When would you choose Webpack over Vite?โ
- Module Federation needed
- Complex existing configuration
- Required plugins only available in Webpack
- Server-side rendering with custom setup
- Need fine-grained control over bundling
Quick Referenceโ
Webpack vs Vite Comparisonโ
| Feature | Webpack 5 | Vite |
|---|---|---|
| Dev Start | Slow (bundle first) | Instant (no bundle) |
| HMR | ~300ms | ~50ms |
| Config | Complex | Simple |
| Plugins | Extensive | Growing |
| Production | Webpack | Rollup |
| Browser Support | All | Modern (ES2015+) |
| Learning Curve | Steep | Gentle |
Common Commandsโ
# Webpack
webpack --mode production
webpack serve --mode development
# Vite
vite build
vite dev
vite preview
# Package.json scripts
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
Key Takeawaysโ
โ Webpack: Mature, powerful, configurable, slower dev experience โ Vite: Fast, modern, simple, best for new projects โ esbuild: Fastest builds, limited ecosystem โ Choice depends on: Project needs, team familiarity, browser support