Tree shaking cần ESM + sideEffects: false trong package.json — lodash dùng CJS nên không tree-shakeable (dùng lodash-es); barrel files (index.ts) có thể phá tree shaking nếu thiếu sideEffects: false.
Tree shaking loại bỏ unused exports dựa trên static analysis của ESM import/export. Điều kiện cần:
- ESM format (không phải CJS
require) sideEffects: falsetrong package.json- không có dynamic imports của cùng module. Tại sao lodash không tree-shakeable: lodash dùng CJS,
require('lodash')load toàn bộ — dùnglodash-eshoặcimport debounce from 'lodash/debounce'(path import). sideEffects field: nếu không có → bundler giả định mọi module có side effects → không eliminate.'sideEffects': falsecho biết bundler an toàn tree-shake toàn bộ package;'sideEffects': ['.css', './src/polyfill.js']exclude files có side effects thật./#__PURE__/ annotation: đánh dấu function call không có side effects:const App = /#__PURE__*/ createApp() — React compiled output dùng pattern này cho JSX. Named exports vs default exports: named exports (export function foo()) tree-shake tốt hơn default exports (export default { foo, bar }) vì bundler biết chính xác tên. Barrel files (index.tsexport từ nhiều files): có thể phá tree shaking nếu có side effects;sideEffects: falsetrong package.json fix vấn đề này. Kiểm tra: Bundle Analyzer trước và sau — thấy unused code → checksideEffectsfield và import patterns
Tree shaking requires ESM + sideEffects: false in package.json — lodash uses CJS and is not tree-shakeable (use lodash-es instead); barrel files (index.ts) can break tree shaking without sideEffects: false.
Tree shaking eliminates unused exports based on static analysis of ESM import/export. Requirements:
- ESM format (not CJS
require) sideEffects: falsein package.json- no dynamic imports of the same module. Why lodash is not tree-shakeable: lodash uses CJS —
require('lodash')loads everything. Uselodash-esor path imports:import debounce from 'lodash/debounce'. The sideEffects field: if absent → bundler assumes all modules have side effects → no elimination.'sideEffects': falsetells the bundler it's safe to tree-shake the entire package;'sideEffects': ['.css', './src/polyfill.js']excludes files with real side effects./#__PURE__/ annotation: marks a function call as side-effect-free:const App = /#__PURE__*/ createApp() — React's compiled output uses this pattern for JSX. Named exports vs default exports: named exports (export function foo()) tree-shake better than default exports (export default { foo, bar }) because bundlers know the exact names. Barrel files (index.tsre-exporting from many files): can break tree shaking if any re-exported file has side effects;sideEffects: falsein package.json fixes this. Verification: use Bundle Analyzer before and after — visible unused code means checkingsideEffectsfield and import patterns