← Concepts

阅读中文版本

Tree Shaking

Tree shaking removes code that is never imported, relying on the static import structure of ES modules to drop dead exports.

delivery

Definition

Tree shaking is dead-code elimination at the module level: a bundler analyses the static import graph of ES modules and removes exports that no reachable code imports. It works because ES module imports are static and analyzable, unlike CommonJS require calls whose targets can be dynamic. Its effectiveness depends on how much the bundler can prove — side effects, dynamic imports, and re-export patterns all limit what can be safely removed.

Context and scope

Applied during production bundling to ship only the code a project uses, especially for large utility and component libraries.

Common misconceptions

  • Tree shaking removes all unused code — it removes what static analysis can prove unused; side effects and dynamic access block removal
  • It works the same on CommonJS — a library shipped as CommonJS usually defeats it, because requires may be dynamic and objects opaque
  • It shrinks application code automatically — it mainly benefits libraries with many small exports; application code is mostly reachable

Anti-patterns

  • Publishing a library as CommonJS only and expecting consumers to tree shake it
  • Omitting sideEffects metadata so bundlers must assume every module has side effects
  • Relying on top-level side effects to register things, pinning otherwise-unused code in the bundle

Related concepts

Authoritative source

https://webpack.js.org/guides/tree-shaking/

What it is

Tree shaking starts from the entry points and follows the static import edges to mark reachable code. Exports never reached are candidates for removal; the bundler then checks whether removing them is safe, accounting for side effects. Because ES modules have a static shape — imports are hoisted and named — the analyser can know exactly which bindings are used, which is what makes precise elimination possible.

Why it matters

Applications often depend on large libraries but use a small fraction of them. Without dead-code elimination, the unused parts still download, parse, and execute, harming startup and bandwidth. Tree shaking lets one well-structured library serve many consumers, each shipping only the pieces it imports, which is why modern libraries are built as many small, side-effect-free modules.

How to use it well

Ship ES modules to consumers and declare sideEffects accurately so the bundler may prune aggressively. Avoid top-level side effects that force code to be kept, keep dynamic imports — which are a deliberate boundary — separate from static ones, and treat any consumer-visible side effect as intentional and documented. Verify the result by analysing the bundle, because tree shaking is an optimisation the tool performs only when it can prove it is safe.