βμ°μ§ μλ μ½λλ λ²λ €λΌ.β β λ²λ€ μ λΆνμν μμ¬κ·λ₯Ό νΈμ΄λ΄λ κΈ°μ
λλΆλΆμ μΉμ±μ μλ§μ λΌμ΄λΈλ¬λ¦¬λ‘ ꡬμ±λ©λλ€.
lodash, date-fns, moment, react-icons, three.js...
μ°λ¦¬κ° μ¬μ©νλ μ½λλ³΄λ€ μ¬μ©νμ§ μλ μ½λκ° ν¨μ¬ λ§μ΅λλ€.
μ΄μ λΈλΌμ°μ κ° κ·Έ λͺ¨λ μ½λλ₯Ό λ€μ΄λ‘λνκ³ , νμ±νκ³ , μ€νν΄μΌ νλ€λ©΄?
νμνμ§ μμ μ½λλ μ¬μ©μ κ²½νμ μ§μ μ μΈ μ±λ₯ λΉμ©μ μ λ°νκ² λ©λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ κ²μ΄ λ°λ‘ Tree Shakingμ λλ€.
βλΉλ λ¨κ³μμ μ¬μ©λμ§ μλ(Dead) μ½λλ₯Ό μ κ±°ν΄ λ²λ€μ λ μκ² λ§λλ κΈ°μ β
Tree Shakingμ μ μ λΆμ(Static Analysis) μ ν΅ν΄
μ¬μ©λμ§ μλ μ½λλ₯Ό βκ°μ§νκ³ μ κ±°βνλ λ²λ€ μ΅μ ν κΈ°μ μ
λλ€.
λ§ κ·Έλλ‘ νΈλ¦¬μμ μ μ°μ΄λ κ°μ§(μ½λ)λ₯Ό βνΈμ΄λ΄λ(shake)β κ³Όμ μ΄μ£ .
| μ©μ΄ | μ€λͺ |
|---|---|
| βTreeβ | λͺ¨λ κ°μ import/export μμ‘΄ κ·Έλν |
| βShakeβ | μ¬μ©λμ§ μλ(exported but unused) μ½λ μ κ±° |

Tree Shaking μλ μ리 (μ¬μ©λμ§ μλ μ½λ μ κ±° κ³Όμ )
Input: { Used: { scope1 } } λ λ²λ€λ¬(Webpack, Rollup λ±)κ° μ€μ λ‘ μ¬μ© μ€μΈ ν¨μ(scope1) λ§ μΆμ νλ€λ κ²μ μλ―Έν©λλ€.scope1κ³Ό scope2λ μ€νλμ§λ§, scope3μ νΈμΆλμ§ μμ΅λλ€.scope3μμ μ¬μ©νλ isNumber() ν¨μλ μ€μ λΉλ κ²°κ³Όμμ μ κ±°(Tree Shaking) λ©λλ€.λͺ¨λ λ¨μμ import/export ꡬ쑰λ₯Ό κ°μ§λ ES6(ESM) νκ²½μμλ,
λ€μμ²λΌ μμ κΈ°λ₯ νλλ§ κ°μ Έμλ μ¬μ€μ μ 체 μ½λκ° λ²λ€λ μ μμ΅λλ€.
// utils.js
export function add(a, b) { return a + b; }
export function sub(a, b) { return a - b; }
export function mul(a, b) { return a * b; }
// main.js
import { add } from './utils.js';
console.log(add(2, 3));
μ μ½λμ κ²°κ³Όλ?
π κΈ°λ³Έμ μΌλ‘ add, sub, mul μΈ ν¨μκ° λͺ¨λ λ²λ€μ ν¬ν¨λ©λλ€.
μλνλ©΄ λ²λ€λ¬κ° βμ΄λ€ ν¨μκ° μ€μ λ‘ μ°μ΄λμ§β λΆμνμ§ μμΌλ©΄ μ 체 λͺ¨λμ κ°μ Έμ€κΈ° λλ¬Έμ
λλ€.
Tree Shakingμ μ΄ μ€ μ¬μ©λ ν¨μ(add)λ§ λ¨κΈ°κ³ , λλ¨Έμ§(sub, mul)λ₯Ό μ κ±°ν©λλ€.

Tree Shaking μ μ© μ ν ꡬ쑰 λΉκ΅
index.jsκ° μ¬λ¬ λͺ¨λ(Module 1~3, file1~4.js)κ³Ό ν¨μλ€μ μ°Έμ‘°νκ³ μμ΅λλ€. νμ§λ§ μ΄ μ€ λ€μμ λͺ¨λκ³Ό ν¨μλ μ€μ μ€νλμ§ μμμλ λ²λ€μ ν¬ν¨λμ΄ μμ΅λλ€.Tree Shakingμ ES Modules(ESM) ꡬ쑰μ μ μ λΆμ(Static Analysis) μ κΈ°λ°μΌλ‘ μλν©λλ€.
| λ¨κ³ | μ€λͺ |
|---|---|
| β μμ‘΄μ± κ·Έλν μμ± | import/export κ΄κ³λ₯Ό λΆμ |
| β‘ μ¬μ© κ²½λ‘ μΆμ | μ€μ λ‘ μ°Έμ‘°λ exportλ§ βνμ±(active)β νμ |
| β’ λ―Έμ¬μ© μ½λ μ κ±° | νμ±λμ§ μμ exportλ λΉλ κ²°κ³Όμμ μ κ±° |
| β£ Dead Code Elimination (DCE) | μμΆκΈ°(Uglify/Terser)κ° λ¨μ μ½λ μ€ λΆμν¨κ³Ό μλ λΆλΆ μ κ±° |
// math.js
export const add = (a, b) => a + b;
export const minus = (a, b) => a - b;
// main.js
import { add } from "./math.js";
console.log(add(2, 3));
λΉλ κ²°κ³Ό (Before)
const add=(a,b)=>a+b;const minus=(a,b)=>a-b;console.log(add(2,3));
λΉλ κ²°κ³Ό (After Tree Shaking)
console.log(((a,b)=>a+b)(2,3));
π minus()λ μ κ±°λ¨

ES Moduleμ Binding ꡬ쑰
exportν λ³μκ° λ³κ²½λλ©΄, μ΄λ₯Ό importν λ€λ₯Έ λͺ¨λμμλ μλμΌλ‘ μ΅μ κ°μ΄ λ°μλ©λλ€.importν μͺ½μμ κ°μ λ³κ²½νλ €λ μλλ λΆκ°λ₯ν©λλ€ (μ½κΈ° μ μ© λ°μΈλ©).Tree Shakingμ΄ μλνλ €λ©΄ λͺ κ°μ§ νμ μ‘°κ±΄μ΄ μμ΅λλ€.
| 쑰건 | μ€λͺ |
|---|---|
| β ES Module(ESM) μ¬μ© | import/export κ΅¬μ‘°λ§ μ μ λΆμ κ°λ₯. require()λ λΆκ°λ₯ |
| β λΆμν¨κ³Ό(side effects)κ° μμ΄μΌ ν¨ | λͺ¨λ λ‘λμ μ€νλλ μ½λκ° μμΌλ©΄ μ κ±° λΆκ° |
| β λ²λ€λ¬ μ΅μ ν μ΅μ νμ±ν | Webpack: usedExports, Rollup: treeshake: true |
| β Production λͺ¨λ λΉλ | Developmentμμλ μ΅μ ν λ―Έμ μ© |
// webpack.config.js
module.exports = {
mode: "production",
optimization: { usedExports: true },
};
π§ μ£Όμ:
CommonJS(require)λ λμ import κ²½λ‘λ₯Ό λΆμν μ μμ΄ Tree Shakingμ΄ λΆκ°λ₯ν©λλ€.

ESM vs CJS: Tree Shakingμ΄ κ°λ₯ν μ΄μ
require()λ₯Ό λ°νμμ μ€ννλ―λ‘, μ΄λ€ λͺ¨λμ΄ μ€μ λ‘ μ¬μ©λ μ§ μ μ λΆμ μμ μ μ μ μμ΅λλ€.import/exportκ° νμΌ μλ¨μμ μ μ μΌλ‘ μ μΈλκΈ° λλ¬Έμ, λ²λ€λ¬(Webpack, Rollup λ±)κ° μμ‘΄ κ·Έλνλ₯Ό μ½κ² λΆμνμ¬ μ¬μ©λμ§ μλ μ½λλ₯Ό μμ νκ² μ κ±°(Tree Shaking) ν μ μμ΅λλ€.| νλͺ© | Tree Shaking | Dead Code Elimination |
|---|---|---|
| λμ μμ | λͺ¨λ κ·Έλν λ¨κ³ | μ½λ μμΆ λ¨κ³ |
| 주체 | λ²λ€λ¬ (Webpack, Rollup λ±) | μμΆκΈ° (Terser, UglifyJS λ±) |
| λμ | λ―Έμ¬μ© export | μ€νλμ§ μλ μ½λ λΈλ‘ |
| ν΅μ¬ μ리 | μ μ μμ‘΄μ± λΆμ | 쑰건 λΆκΈ° μ κ±° |
| μμ | μ¬μ©λμ§ μμ ν¨μ μ κ±° | if (false) { ... } λΈλ‘ μ κ±° |
κ²°κ΅ Tree Shakingμ DCEμ μ μ²λ¦¬ λ¨κ³λΌκ³ λ³Ό μ μμ΅λλ€.
β λ²λ€λ¬κ° β무μλ―Έν exportβλ₯Ό μ κ±°νκ³ ,
β μμΆκΈ°κ° β쑰건μ μ λ μ€νλμ§ μλ μ½λβλ₯Ό μ κ±°ν©λλ€.
| μμΈ | μ€λͺ | ν΄κ²°μ± |
|---|---|---|
| β οΈ CommonJS | require()λ μ μ λΆμ λΆκ° | ESM(import/export)λ‘ λ³κ²½ |
| β οΈ λμ import κ²½λ‘ | λ¬Έμμ΄ μ‘°ν©μΌλ‘ κ²½λ‘ κ²°μ μ λΆμ λΆκ° | μ μ λ¬Έμμ΄ μ¬μ© |
| β οΈ λΆμν¨κ³Ό(side effect) | import μ μ μ λ³μ μμ , μ½μ μΆλ ₯ λ± | λͺ¨λμ βμμ(pure)βνκ² μ μ§ |
| β οΈ λ°°λ΄ νμΌ(index.js) | λͺ¨λ λͺ¨λμ μ¬export νλ©΄ λͺ¨λ ν¬ν¨ | μ§μ κ²½λ‘λ‘ import |
| β οΈ ESLint / Babel νΈλμ€νμΌ | require κΈ°λ° λ³ν μ Tree Shaking κΉ¨μ§ | modules: false μ€μ μ μ§ |
// babel.config.json
{
"presets": [["@babel/preset-env", { "modules": false }]]
}

λ°°λ΄ νμΌ import λ¬Έμ λμ
index.jsμμ λͺ¨λ λͺ¨λμ νκΊΌλ²μ exportνλ©΄, μ¬μ©λμ§ μλ ν¨μκΉμ§ λͺ¨λ λ²λ€ νμΌ(bundle.js) μ ν¬ν¨λ©λλ€.Tree Shakingμ βμ½λλ₯Ό μ§μ΄λ€βλ νμκ° μλλλ€.
βμ¬μ©μμκ² λλ¬νμ§ μλ μ½λκ° μ‘΄μ¬νμ§ μλλ‘ νλ€βλ μμΉμ
λλ€.
μ¦, μ±λ₯ μ΅μ νμ λͺ©μ μ βμ½λλ₯Ό λ μ°λ κ²βμ΄ μλλΌ,
βμ¬μ©νμ§ μλ μ½λλ₯Ό μμ λ°°ν¬νμ§ μλ κ²βμ΄μ£ .
μ΄κ±΄ κ²°κ΅ βμ¬μ©μμ λ€μ΄λ‘λ μκ°μ μ€μ΄λ UX μ΅μ νβμ΄κΈ°λ ν©λλ€.
Tree Shakingμ κ°λ²Όμ΄ μ¬μ©μ κ²½νμ μν μ¬μ μ²μκΈ°λ€.
μ λ tree shakingμ λν΄ κ°λ¨ν μ΄ν΄νκ³ λμ΄κ°λλ° μμ£Ό μμΈν μ¨μ£Όμ μ κΉκ² μ΄ν΄ν μ μμμ΅λλ€. μ΅κ·Όμ λ°°λ΄ νμΌμ΄ μ¬μ©λ μ½λλ₯Ό λ³΄κ³ λ°°λ΄ νμΌ μ¬μ©μ΄ κ°λ μ± ν₯μμ λμμ΄ λλ€κ³ λκ»΄ λ€μμ μ¨λ¨Ήμ΄λ΄μΌκ² λ€λ μκ°μ νλλ° tree shaking μΈ‘λ©΄μμλ μ€νλ € μ’μ§ μκ΅°μ! μλ‘ λ°°μκ°λλ€π€ tree shakingμ μ μ 쑰건과 μ€ν¨ ν΄κ²° μ¬λ‘ λ± μ€μ μ μΈ λΆλΆλ€λ μ μμ±ν΄μ£Όμ μ μ νλ‘μ νΈμ tree shakingμ μ μ©ν μΌμ΄ μμ λ λ μ½μ΄λ³΄λ¬ μμΌκ² μ΄μπ
ESMμ λ°μΈλ© ꡬ쑰 μ€λͺ λλΆμ λͺ¨λμ μ΅μ κ°μ λ°μν μ μλ€λ κ²μ μλ‘ μκ² λμκ³ μ΄ λ°μΈλ© ꡬ쑰 λλΆμ 컀μ€ν ν μ μλ μ리μ λν΄μ λ κΉκ² μ΄ν΄ν μ μμμ΅λλ€.
νΈλ¦¬μ °μ΄νΉμ μλ λ¨κ³λ νλ₯Ό ν΅ν΄ μ½κ² μ μ μμ΄ dead code eliminationκ³Όμ μ°¨μ΄, μμμ λν΄ λ°°μκ°λλ€