Webpack & Vite
Configure Webpack and Vite for production - code splitting, tree shaking, caching, and fast HMR to ship optimized bundles and quick dev builds.
skill: Webpack & Vite category: Web Development tags: [Webpack, Vite, Build Tools, Bundler, Frontend] readingTime: 6
Choose Vite for new projects - it uses native ESM in dev mode for near-instant startup and HMR, and Rollup for production builds. Use Webpack for legacy projects with complex plugin requirements (Module Federation, custom loaders) or when migrating is too costly. Don't over-configure - start with defaults and only customize when you have a specific performance measurement showing a need.
Workflow
- Use Vite for new projectsVite starts in milliseconds (no bundling in dev), has instant HMR, and produces optimized Rollup bundles for production - with a much simpler config than Webpack.
- Configure Webpack for productionWebpack's mature plugin ecosystem handles complex cases: Module Federation for micro-frontends, custom loaders, and legacy browser support.
- Implement code splittingLoading all code upfront increases Time to Interactive. Route-based code splitting loads only the code needed for the current page.
- Optimize tree shakingTree shaking removes unused exports from the final bundle. It only works correctly with ES modules and side-effect-free packages.
- Analyze and monitor bundle sizeBundle size directly impacts load time - especially on mobile. Regular analysis prevents bundle bloat from sneaking in via dependencies.
Output Format
Vite config: manual chunks, proxy, and build target. Webpack: contenthash output, splitChunks, and bundle analyzer.
Vite checklist:
☐ manualChunks for vendor/router/ui libraries
☐ build.target: 'es2020' or browserslist
☐ server.proxy for API calls in dev
☐ bundle visualizer in CI
☐ size-limit budget check on PRExamples
Edge Cases & Gotchas
- contenthash vs chunkhash - contenthash changes only when the file's content changes - ideal for long-term caching. chunkhash changes when any file in the chunk changes - too aggressive. Always use contenthash for assets.
- Circular dependencies - Circular imports (A imports B which imports A) cause undefined at runtime. Use madge or webpack circular-dependency-plugin to detect and break them.
- CSS in JS vs CSS Modules - CSS-in-JS (styled-components) adds runtime overhead and bundle size. CSS Modules (import styles from './Button.module.css') have zero runtime cost and full tree shaking.
- Webpack Module Federation - Module Federation enables micro-frontends - loading remote components from separate deployed bundles at runtime. Available only in Webpack 5; Vite has a community plugin but it's experimental.
When to Break These Rules
- Use esbuild directly (not Vite) for build scripts, CLI tools, or server-side bundling - it's 100x faster than Webpack and doesn't need the Vite dev server wrapper.
- Use Next.js or Remix built-in bundling instead of configuring Webpack/Vite manually - framework bundlers are pre-configured with SSR, image optimization, and edge support.
Reference Files
https://vitejs.dev/guide/https://webpack.js.org/configuration/