Understanding Tree Shaking in Webpack: Principles, Usage, and Side‑Effects
This article explains how Webpack’s tree shaking removes dead code and unused assets by analyzing ES6 module imports, demonstrates configuration for development and production builds, and discusses the role of sideEffects in achieving optimal bundle size.
JavaScript applications are usually loaded over the network, so smaller files lead to faster execution; tree shaking is a technique that eliminates unused code to reduce bundle size.
Tree shaking (literally “shaking the tree”) refers to the process where a bundler walks the module dependency graph from the entry point, marks code that is actually used, and discards the rest.
For example, in // utils.js export function sum(x, y) { return x + y; } export function sub(x, y) { return x - y; } only sum is imported in // index.js import { sum } from "./utils"; console.log(sum(1, 2)); , so the generated bundle contains only the sum implementation.
The resulting bundle after tree shaking looks like (()=>{"use strict";console.log(3)})(); , showing that the unused sub function has been removed.
Tree shaking also removes unused JSON data. Given // main.json { "a": "a", "b": "b" } and // index.js import main from "./main.json"; console.log(main.a); , the final bundle includes only the reference to a , discarding b .
The underlying principle is that the bundler builds an Abstract Syntax Tree (AST) from the entry file, follows all static import / export statements, marks reachable nodes, and then prunes the unmarked nodes.
Tree shaking works only with ES6 module syntax because it relies on static analysis; CommonJS’s dynamic require cannot be safely analyzed. When using Babel, ensure @babel/preset-env does not transform modules to CommonJS (set modules: false ).
In development mode, a typical // webpack.config.js module.exports = { mode: "development", devtool: false, optimization: { usedExports: true } }; configuration marks unused exports, and the bundle shows comments such as /* unused harmony export sub */ indicating that sub was eliminated.
In production mode, after minification the unused code disappears entirely, and the remaining functions are often mangled, e.g., function r(e){return e*e*e}n.a=r for the sum function.
Side effects are pieces of code that run when a module is imported, even if no export is used. Webpack 4 introduced the sideEffects flag in package.json ; setting "sideEffects": false tells Webpack that a package has no side effects, allowing aggressive tree shaking.
For instance, // a.js export default { a() { console.log('a'); } } has no side effects and can be removed if unused, whereas // b.js function b(){ console.log('b'); } Array.prototype.fun = () => {}; export default { b }; has a side effect (modifying Array.prototype ) and will be retained unless sideEffects: false is explicitly declared.
To keep necessary side‑effectful files (e.g., polyfills, CSS), list them in the sideEffects array, such as { "sideEffects": ["./src/b.js", "*.css"] } .
Summary :
Use ES6 import / export syntax.
Avoid converting modules to CommonJS with Babel.
Enable optimization: { usedExports: true, minimize: true } in Webpack.
Mark packages without side effects using sideEffects: false or an explicit list.
References:
Tree shaking principles and applications – https://segmentfault.com/a/1190000040037144
Webpack documentation on tree shaking – https://webpack.docschina.org/guides/tree-shaking/
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.