๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป dev

๋ชจ๋“ˆ ์‹œ์Šคํ…œ

์ธ๋„ค์ผ

๐Ÿ—ฃ๏ธ import๊ณผ require์˜ ์ฐจ์ด๋ฅผ ์•Œ๊ณ  ๊ณ„์‹œ๋‚˜์š”? 

 

๐Ÿค” ๋…ธ๋“œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” require ๋งŽ์ด ๋ณธ ๊ฑฐ ๊ฐ™๊ณ , react์—์„œ  import ๋งŽ์ด ์ผ๋˜ ๊ฑฐ ๊ฐ™์€๋ฐ? 

import๊ณผ require์— ๋Œ€ํ•ด ์•Œ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์ด๋ผ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•œ๋‹ค.

์˜ค๋Š˜์€ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์ด ๋ฌด์—‡์ด๊ณ , ์–ด๋–ค ๊ฒƒ๋“ค์ด ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ์˜ ํŠน์ง•๊ณผ ์žฅ๋‹จ์ ์„ ์‚ดํŽด๋ณด์ž.

JS ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์ด๋ž€?

์˜ˆ์ „ ์›น์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ด๋‹นํ•˜๊ณ  ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋“ค์€ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ ์ •๋„์˜€๋‹ค.

ํ•˜์ง€๋งŒ ์ ์ฐจ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์—ญํ• ์ด ๊ฑฐ๋Œ€ํ•ด์ง€๊ณ , ๊ธฐ๋Šฅ๋“ค์„ ๋งŒ๋“ค๋ฉด์„œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฉฐ dependency๋ฉฐ ๊ด€๋ฆฌํ•  ๊ฒƒ๋„ ๋น„๋ก€(์ •๋น„๋ก€๋Š” ์•„๋‹ ์ˆ˜๋„?)ํ•ด์„œ ๋ฐฉ๋Œ€ํ•ด์กŒ๋‹ค.

๋ชจ๋“ˆ ์‹œ์Šคํ…œ์€ ์ด๋ ‡๊ฒŒ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šด ์Šค์ฝ”ํ”„ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์•ˆ์œผ๋กœ ๋“ฑ์žฅํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

๋ชจ๋“ˆ๋Ÿฌ js๊ฐ€ ์•„๋‹Œ ์ฝ”๋“œ(์™ผ์ชฝ)์™€ ๋ชจ๋“ˆ๋Ÿฌ js ์ธ ์ฝ”๋“œ

JS ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์„ ์•Œ์•„์•ผ ํ•˜๋Š” ์ด์œ 

ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‹ค ๋ณด๋ฉด ํ”„๋กœ์ ํŠธ๋ฅผ ๋„˜๋‚˜๋“ค๋ฉฐ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค์„ ๋ณต์‚ฌ+๋ถ™์—ฌ๋†“๊ธฐ ๋ฐ˜๋ณต์ž‘์—…์„ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋‹ค.

๊ทผ๋ฐ ํ•œ ๊ณณ์˜ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ˆ˜์ž‘์—…์œผ๋กœ ํ”„๋กœ์ ํŠธ๋“ค ๋ชจ๋‘์—์„œ sync๋ฅผ ๋งž์ถ”๋Š” ์ž‘์—…์„ ํ•ด์•ผ ํ•˜๋Š” ์ˆ˜๊ณ ์Šค๋Ÿฌ์›€์ด ์žˆ๋‹ค.

 

์ด ์ž‘์—…์— ์ง€์ณ์„œ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ์†์‰ฝ๊ฒŒ ๊ณตํ†ต ๊ธฐ๋Šฅ๋“ค์„ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ๊ณ , ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ์ผ๊ด„+์ž๋™ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค๋ฉด, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งŒ๋“ค์–ด์„œ dependency๋กœ ์žฌ์‚ฌ์šฉํ•ด๋ณด๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. 

 

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋”ฑ! ๋งŒ๋“ค๊ณ  ์ด์ œ ๋งˆ์ง€๋ง‰ ํผ๋ธ”๋ฆฌ์‹ฑ ๋‹จ๊ณ„์—์„œ ๊ณ ๋ฏผ๋“ค์ด ์ƒ๊ฒจ๋‚œ๋‹ค.

 

1. tree shaking์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•?

2. JS ๋ชจ๋“ˆ ์‹œ์Šคํ…œ ์ค‘์—์„œ ๋ญ˜ ์จ์•ผ ํ•˜์ง€?

 

์ด๋•Œ JS๋ชจ๋“ˆ ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, ์ด ๊ณ ๋ฏผ๋“ค์— ๋Œ€ํ•œ ๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

JS ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์˜ ์ข…๋ฅ˜

CommonJS AMD: Async Module Definition UMD: Universal Module Definition ECMAScript Module (ESM)
require ์™€ module.exports require require์™€ module.exports import์™€ export
- ES5 ๋ชจ๋“ˆ ์‹œ์Šคํ…œ 
- node๋กœ ๊ตฌํ˜„

- ๋ชจ๋“ˆ ์„ค์น˜ ์‹œ ์„œ๋ฒ„์‚ฌ์ด๋“œ์— ์“ฐ์ž„
- import๋ฅผ ํ•˜๋ฉด object๋ฅผ ๋ฐ˜ํ™˜๋ฐ›๋Š”๋‹ค
  ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์ด ์žˆ๋‹ค: 
     -  tree shaking์ด ๋ถˆ๊ฐ€๋Šฅ
    - ํ”„๋กœํผํ‹ฐ ๊ฒ€์ƒ‰(property lookup)์ด ๋Ÿฐํƒ€์ž„์— ์ง„ํ–‰๋˜๋ฏ€๋กœ ์ •์ ๋ถ„์„(static analyzing)์ด ๋ถˆ๊ฐ€๋Šฅ
- ํ•ญ์ƒ object์˜ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ›์œผ๋ฏ€๋กœ ๋ชจ๋“ˆ ์ž์ฒด์˜ ์ฆ‰๊ฐ์ ์ธ ๋ณ€ํ™”๋Š” ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š”๋‹ค
- ์ˆœํ™˜ (cyclic) dependency ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค
- syntax๊ฐ€ ๊ฐ„๋‹จํ•˜๋‹ค
- ES5 ๋ชจ๋“ˆ ์‹œ์Šคํ…œ 
- RequireJs๋กœ ๊ตฌํ˜„
- ๋ชจ๋“ˆ์„ ๋™์ ์œผ๋กœ ๋กœ๋“œํ•˜๊ณ  ์‹ถ์„ ๋•Œ ํด๋ผ์ด์–ธํŠธ (๋ธŒ๋ผ์šฐ์ €)์—์„œ ์“ฐ์ž„
- syntax๊ฐ€ ๋ณต์žกํ•˜๋‹ค
- ES5 ๋ชจ๋“ˆ ์‹œ์Šคํ…œ 
- AMD์™€ CMJ ํ™˜๊ฒฝ ๋ชจ๋‘์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
- CommonJS์˜ syntax์™€ AMD์˜ ๋น„๋™๊ธฐ ๋กœ๋”ฉ
- UMD๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‘ ํ™˜๊ฒฝ์—์„œ ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๋ฉด์„œ๋„ ์ „์—ญ ๋ณ€์ˆ˜ ์„ ์–ธ๋„ ์ง€์›ํ•œ๋‹ค
- ๋”ฐ๋ผ์„œ UMD ๋ชจ๋“ˆ์€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค
- ES6 ๋ชจ๋“ˆ ์‹œ์Šคํ…œ 
- ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
- ๋Ÿฐํƒ€์ž„/ ์ •์ (static) ๋ชจ๋“ˆ ๋กœ๋”ฉ ์ง€์›
- import๋ฅผ ํ•˜๋ฉด binding value (์‹ค์ œ ๊ฐ’)์„ ๋ฐ˜ํ™˜๋ฐ›๋Š”๋‹ค
   - ๋”ฐ๋ผ์„œ ๋ชจ๋“ˆ ์ž์ฒด์˜ ์ฆ‰๊ฐ์ ์ธ ๋ณ€ํ™”๊ฐ€ ๋ฐ˜์˜๋œ๋‹ค
- ์ •์  ๋ถ„์„ (static analyzing) ๊ฐ€๋Šฅ : import/export๋ฅผ ์ปดํŒŒ์ผ ๋„์ค‘์— ์ •์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋‹ค
  -  ์ •์ ๋ถ„์„์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ Tree shaking์ด ๊ฐ€๋Šฅํ•˜๋‹ค (ES6์ง€์›)
- CJS์— ๋น„ํ•ด ์ˆœํ™˜ dependency ๊ด€๋ฆฌ๊ฐ€ ์šฉ์ดํ•˜๋‹ค

 

๐ŸŒด tree shaking์ด๋ž€?
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ด€์ ์—์„œ๋Š” tree shaking์ด๋ž€ ์ฃฝ์€ ์ฝ”๋“œ ์ œ๊ฑฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ด๋‹ค.

ESM ํŠน์ง• ์‚ดํŽด๋ณด๊ธฐ (ft. CJS์™€ ๋น„๊ต)

ESM export ๋ฐฉ์‹ ๋‘ ๊ฐ€์ง€ : Named exports์™€ default exports

 

ESM export ๋ฐฉ์‹์—๋Š” Named exports (๋ชจ๋“ˆ ๋‹น ์—ฌ๋Ÿฌ๊ฐœ)์™€ default exports (๋ชจ๋“ˆ ๋‹น ํ•˜๋‚˜)๊ฐ€ ์žˆ๋‹ค.

๋™์‹œ์— ๋‘˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜๋‚˜, ๋˜๋„๋ก์ด๋ฉด ๋ถ„๋ฆฌํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

Named exports ์‚ฌ์šฉ

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

// ์ „์ฒด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ
//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

 

CJS์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ผํ•˜๊ฒŒ ์ž‘์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค.

//------ lib.js ------
var sqrt = Math.sqrt;
function square(x) {
    return x * x;
}
function diag(x, y) {
    return sqrt(square(x) + square(y));
}
module.exports = {
    sqrt: sqrt,
    square: square,
    diag: diag,
};

//------ main.js ------
var square = require('lib').square;
var diag = require('lib').diag;
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

 

default exports ์‚ฌ์šฉ

// ํ•จ์ˆ˜ default export 
//------ myFunc.js ------
export default function () {} // no semicolon!

//------ main1.js ------
import myFunc from 'myFunc';
myFunc();


// ํด๋ž˜์Šค default export 

//------ MyClass.js ------
export default class {} // no semicolon!

//------ main2.js ------
import MyClass from 'MyClass';
const inst = new MyClass();

// ์„ ์–ธ label ๋ฐฉ์‹
export default function foo() {} // no semicolon!
export default class Bar {} // no semicolon!

// default-export ๊ฐ’์„ ์ง์ ‘ export ํ•˜๊ธฐ
export default function () {} // no semicolon! (์ต๋ช…ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉ)
export default class {} // no semicolon!
export default 'abc';
export default foo();
export default /^xyz$/;
export default 5 * 7;
export default { no: false, yes: true };

 

default exports ๋ฐฉ์‹์„ ๋ณด๋ฉด default exports์˜ ํ”ผ์—ฐ์‚ฐ์ž (export ํ•˜๋Š” ๋Œ€์ƒ)์ด ํ‘œํ˜„์‹์ผ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ‘œํ˜„์‹์ด ์•„๋‹Œ ์„ ์–ธ๋ฌธ์ด๋‹ค. ํ‘œํ˜„์‹์œผ๋กœ ํ•ด์„๋˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์ค˜์•ผ ํ•œ๋‹ค.

export default (function () {});

 

ESM export/import ์„ ์–ธ์€ ์ตœ์ƒ๋‹จ์—

 

ESM์€ ์ •์  ๋ชจ๋“ˆ์„ ์ง€์›ํ•œ๋‹ค๊ณ  ํ–ˆ๋‹ค. ์ฆ‰, ์กฐ๊ฑด๋ถ€์ ์œผ๋กœ import/export๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†๋‹ค. 

๋”ฐ๋ผ์„œ ํ•ด๋‹น ์Šค์ฝ”ํ”„์˜ ์ตœ์ƒ๋‹จ์— ์œ„์น˜์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.

 

ESM import ์€ ํ˜ธ์ด์ŠคํŒ…๋œ๋‹ค

 

import ํ•œ ๋ชจ๋“ˆ์€ ํ˜„์žฌ ์Šค์ฝ”ํ”„์˜ ์ตœ์ƒ๋‹จ์œผ๋กœ ๋Œ์–ด์˜ฌ๋ ค์ง€๋Š” ํ˜ธ์ด์ŠคํŒ…์ด ๋ฐœ์ƒํ•œ๋‹ค.

 

ESM import ๋œ ๊ฐ’์€ export ํ•œ ๊ฐ’์˜ ์ฝ๊ธฐ ์ „์šฉ LIVE(๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ฆ‰๊ฐ ๋ฐ˜์˜๋œ) ๊ฐ’์ด๋‹ค

 

CJS์™€ ๋‹ฌ๋ฆฌ ESM์€ ์ˆœํ™˜ dependency๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์šฉ์ดํ•˜๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ๋ฐ”๋กœ export ํ•œ ESM์€ ์ฝ๊ธฐ ์ „์šฉ(read-only)์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ฝ๊ธฐ ์ „์šฉ์ด๋ผ๋Š” ๊ฒŒ ๋ฌด์Šจ ์˜๋ฏธ์ผ๊นŒ?  import ํ•ด์˜จ ๊ฐ’์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๊ณง๋ฐ”๋กœ ๋ฐ˜์˜๋˜๋Š” ๋‹ค์Œ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ž.

//------ lib.js ------
export let counter = 3;
export function incCounter() {
    counter++;
}

//------ main.js ------
import { counter, incCounter } from './lib';

// import ํ•ด์˜จ ๊ฐ’ value `counter`๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๊ณง๋ฐ”๋กœ ์ ์šฉ๋œ๋‹ค
console.log(counter); // 3
incCounter();
console.log(counter); // 4

 

CJS๋Š” import ํ•ด์˜จ ๊ฐ’์ด ๋ณต์‚ฌ๋ณธ์ธ ๋ฐ˜๋ฉด, ESM์€ exportํ•œ ๊ฐ’์ด ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ’์ด๋ผ๊ณ  ํ–ˆ๋‹ค.

๋ฐ”์ธ๋”ฉ๋œ ๊ฐ’์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฆ‰๊ฐ ๋ฐ˜์˜ํ•œ export ํ•œ ๊ฐ’์˜ ์ฝ๊ธฐ ์ „์šฉ ๊ฐ’์ด๋‹ค. 

 

์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๊ฐ’์„ importํ•ด์˜ค๋ฉด import์ž‘์—…์ด ์–‘๋ฐฉํ–ฅ์ด๊ฒŒ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ชจ๋“ˆ๋กœ ์ฝ”๋“œ๋ฅผ splitํ•ด๋„ import ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ์›๋ž˜๋Œ€๋กœ ์ž‘๋™ํ•˜๊ณ ,  

์ˆœํ™˜ dependency๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์ด ๋น„์ •์ƒ์ (?)์ธ import๋„ ์ง€์›ํ•ด ์ค€๋‹ค.

 

๐Ÿค” ๊ทผ๋ฐ ์• ์ดˆ์— ์ˆœํ™˜ dependency๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€? ์‹ถ์„ ์ˆ˜ ์žˆ๋‹ค. 

์ด์— ๊ด€ํ•ด์„œ๋Š” ๋‹ค์Œ์—์„œ ๋‹ค๋ค„๋ณด์ž.

๐Ÿ‘ป ์ˆœํ™˜ dependency๋Š” ๋‚˜์œ ๊ฒƒ๋งŒ์€ ์•„๋‹ˆ๋‹ค. ํŠนํžˆ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์ด๋Ÿฐ dependency๋ฅผ ์˜คํžˆ๋ ค ์„ ํ˜ธํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค๋ฉด, DOM ๊ฐ์ฒด์™€ ๊ฐ™์ด ๋ถ€๋ชจ์™€ ์ง€์‹ ๊ฐ„์— ์ฐธ์กฐ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
์ผ๋ฐ˜์ ์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ ์ˆœํ™˜ dependency๋Š” ๋””์ž์ธ์— ์‹ ์ค‘์„ ๊ฐ€ํ•˜๋ฉด ํ”ผํ•  ์ˆ˜๋Š” ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์‹œ์Šคํ…œ์ด ์ปค์ง€๊ณ , ํŠนํžˆ ๋ฆฌํŽ™ํ„ฐ๋ง ๋„์ค‘์—๋Š” ์ˆœํ™˜ dependency๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ชจ๋“ˆ ์‹œ์Šคํ…œ์ด ์ˆœํ™˜ dependency๋ฅผ ์ง€์›ํ•˜๋ฉด ์‹œ์Šคํ…œ์ด ๊ณ ์žฅ ๋‚˜์ง€ ์•Š๊ณ ๋„ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ์œ ์šฉํ•˜๋‹ค.

 

 

ESM ์€ ์ˆœํ™˜ dependency๋ฅผ ์ง€์›ํ•œ๋‹ค

 

๋ชจ๋“ˆ A์™€ B๊ฐ€ ์„œ๋กœ๋ฅผ import ํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ์ˆœํ™˜ dependency๋ฅผ ์ง€๋…”๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์ˆœํ™˜ dependency๋Š” ๋ชจ๋“ˆ ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„(coupling)์„ ๋†’์—ฌ ๋ชจ๋“ˆ ๋ถ„๋ฆฌ์˜ ๋ชฉ์ ์„ ํ—ค์น˜๋ฏ€๋กœ ์ง€์–‘ํ•ด์•ผ ํ•œ๋‹ค.

 

ํ•˜์ง€๋งŒ ๋ถˆ๊ฐ€ํ”ผํ•  ๊ฒฝ์šฐ์— ์ˆœํ™˜ dependency๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์€ ์ด๋ฅผ ์ง€์›์„ ํ•ด์•ผ ํ•œ๋‹ค.

 

๋‹ค์Œ์€ CJS์™€ ESM์ด ๊ฐ๊ฐ ์ˆœํ™˜ dependency๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ์‹์ด๋‹ค.

๋‹ค๋งŒ ์–ด๋Š ๋ชจ๋“ˆ์ด๋“  ๊ฐ„์— ์ˆœํ™˜ dependency๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ชจ๋“ˆ body ๋‚ด๋ถ€์—์„œ import์— ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์ž.

// CJS์—์„œ์˜ ์ˆœํ™˜ dependency ํ•ธ๋“ค๋ง
//------ a.js ------
var b = require('b');
function foo() {
    b.bar();
}
exports.foo = foo;

//------ b.js ------
// a๊ฐ€ ๋ฒˆ์ € b์—์„œ import๋˜๋ฉด export๊ฐ€ ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— a์˜ object๋ฅผ ๋ฐ›๋Š”๋‹ค
// ๋”ฐ๋ผ์„œ b๋Š” a.foo๋ฃฐ ์ตœ์ƒ๋‹จ์ด ์•„๋‹Œ a์˜ ์‹คํ–‰์ด ๋๋‚˜๊ณ  ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•œ ๋’ค์—์„œ์•ผ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.
var a = require('a'); 
function bar() {
    if (Math.random()) {
        a.foo(); // bar()์ด ๊ทธ ํ›„ ํ˜ธ์ถœ๋˜๋ฉด ์‹คํ–‰
    }
}
exports.bar = bar;

 

CJS ๋ฐฉ์‹์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์ ๋“ค์ด ์žˆ๋‹ค.

1. node.js ์Šคํƒ€์ผ์˜ ๋‹จ์ผ ๊ฐ’ export๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. object ๋Œ€์‹  ๋‹จ์ผ ๊ฐ’์„ export ํ•ด์•ผ ํ•œ๋‹ค.

  module.exports = function () { ··· };

 

์•ž์„œ ์‚ดํŽด๋ณธ ์˜ˆ์—์„œ ๋งŒ์•ฝ์— ๋ชจ๋“ˆ a ๊ฐ€ ์œ„์™€ ๊ฐ™์ด export ๋œ๋‹ค๋ฉด, b์˜ ๋ณ€์ˆ˜ a๋Š” ํ• ๋‹น์ด ๋˜๊ธฐ ์ „๊นŒ์ง€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐ˜์˜๋˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. 

2.  named exports๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์ฆ‰, ๋ชจ๋“ˆ b๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด foo๋ฅผ import ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— a.foo๋กœ ์ฐธ์กฐํ•  ์ˆ˜๋ฐ–์— ์—†๋‹ค.

  var foo = require('a').foo; // undefined

 

ํ•ต์‹ฌ์€ import๋ฅผ ํ•˜๋Š” ๋ชจ๋“ˆ๊ณผ export๋ฅผ ํ•˜๋Š” ๋ชจ๋“ˆ ๋ชจ๋‘ ์ˆœํ™˜ dependency์— ๋Œ€ํ•œ ๋ช…์‹œ์  ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์•ผ ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

 

๋Œ์•„์™€์„œ ESM์ด ์ˆœํ™˜ dependency๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ดํŽด๋ณด๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž๋™์ ์œผ๋กœ ์ง€์›์„ ํ•ด์ค€๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

//------ a.js ------
import {bar} from 'b'; // b ๋ชจ๋“ˆ์˜ bar์˜ ์ฝ๊ธฐ-์ „์šฉ ๋ฒ„์ „ import
export function foo() {
    bar(); // ์ฝ๊ธฐ ์ „์šฉ์˜ ๊ฐ’, ์˜ค๋ฆฌ์ง€๋„ ๋ฐ์ดํ„ฐ bar๋ฅผ ๊ฐ„์ ‘์ ์œผ๋กœ ์ฐธ์กฐ
}

//------ b.js ------
import {foo} from 'a'; // a๋ชจ๋“ˆ์˜ foo๋ฅผ ์ฝ๊ธฐ-์ „์šฉ ๋ฒ„์ „์œผ๋กœ import
export function bar() {
    if (Math.random()) {
        foo(); // foo์˜ ์˜ค๋ฆฌ์ง€๋„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ„์ ‘์ ์œผ๋กœ ์ฐธ์กฐ 
    }
}

 

import๋Š” ์ฝ๊ธฐ-์ „์šฉ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ์ ์„ ํ†ตํ•ด ์ˆœํ™˜ dependency๊ฐ€ ์žˆ์–ด๋„ ํ•ญ์ƒ ์˜ค๋ฆฌ์ง€๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์•„๊ฐ€๋„๋ก ๋ณด์žฅํ•œ๋‹ค.

 

ESM๋กœ import ํ•œ ๊ฐ’์€ export ๊ฐ’์˜ ์ฝ๊ธฐ-์ „์šฉ LIVE ๋ฒ„์ „, CJS๋Š” export ๊ฐ’์˜ ๋ณต์‚ฌ๋ณธ์„ import ํ•œ๋‹ค

 

๋ณต์‚ฌ๋ณธ์„ import ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” CJS์˜ ๋ฌธ์ œ์ ์„ ์‚ดํŽด๋ณด์ž.

//------ lib.js ------
var counter = 3;
function incCounter() {
    counter++;
}
module.exports = {
    counter: counter, // (A)
    incCounter: incCounter,
};

//------ main1.js ------
var counter = require('./lib').counter; // (B)
var incCounter = require('./lib').incCounter;

// importํ•œ ๊ฐ’์€ ๋ณต์‚ฌ๋ณธ์˜ ๋ณต์‚ฌ๋ณธ์ด๋‹ค 
console.log(counter); // 3
incCounter();
console.log(counter); // 3

// importํ•œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
counter++;
console.log(counter); // 4

 

export ํ•œ ๊ฐ์ฒด์˜ ๊ฐ’์— ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๋ฉด ๋˜๋‹ค์‹œ export์‹œ์— ๋ณต์‚ฌ๋˜์–ด ๋ณต์‚ฌ๋ณธ์ด import ์‚ฌ์šฉ์ฒ˜์— ์ „๋‹ฌ๋œ๋‹ค.

๋ฐ˜๋ฉด์— ESM์—์„œ๋Š” export๊ฐ’์˜ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ LIVE(๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ฆ‰๊ฐ ๋ฐ˜์˜๋œ ๊ฐ’)์ด ์ „๋‹ฌ๋œ๋‹ค.

๋‹ค์Œ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ž.

//------ lib.js ------
export let counter = 3;
export function incCounter() {
    counter++;
}

//------ main1.js ------
import { counter, incCounter } from './lib';

// importํ•œ ๊ฐ’ counter๋Š” ๋ผ์ด๋ธŒ(๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ฆ‰๊ฐ ๋ฐ˜์˜๋œ) ๊ฐ’์ด๋‹ค.
console.log(counter); // 3
incCounter();
console.log(counter); // 4

// ์ฝ๊ธฐ ์ „์šฉ ๊ฐ’์ธ import๋œ counter์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.
counter++; // TypeError

 

๋‹ค๋งŒ, import๊ฐ’์˜ ๊ฐ์ฒด ์†์„ฑ์€ ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•˜๋‹ค.

//------ lib.js ------
export let obj = {};

//------ main.js ------
import { obj } from './lib';

obj.prop = 123; // OK
obj = {}; // TypeError

 

ESM๋Š” ์ •์ (static) ๋ชจ๋“ˆ ๊ตฌ์กฐ๋ฅผ ๊ฐ•์ œํ•œ๋‹ค

 

ํ˜„์žฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ชจ๋“ˆ์€ ๋™์  ๊ตฌ์กฐ๋ฅผ ๋ค๋‹ค. ๋”ฐ๋ผ์„œ ๋Ÿฐํƒ€์ž„์— ์–ด๋–ค ๋ชจ๋“ˆ์ด import/export ๋˜๋Š”์ง€ ๋™์ ์œผ๋กœ ๋ณ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ •์  ๋ชจ๋“ˆ ๊ตฌ์กฐ๋ฅผ ์ง€๋…”๋‹ค๋Š” ๊ฒƒ์€  ์ปดํŒŒ์ผ ์‹œ๊ธฐ์— import/export๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์•„๋„ import/export ๊ฐ’์„ ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

๋ฐ˜๋ฉด์— CJS๋Š” ์ •์  ๋ชจ๋“ˆ ๊ตฌ์กฐ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.  ๋‹ค์Œ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด์ž.

์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผ์ง€๋งŒ ์–ด๋–ค ๊ฐ’์ด import ๋ ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

var my_lib;
if (Math.random()) {
    my_lib = require('foo');
} else {
    my_lib = require('bar');
}

 

๋‹ค์Œ ์˜ˆ์‹œ ๋˜ํ•œ ์‹คํ–‰์„ ํ•ด์•ผ์ง€๋งŒ ์–ด๋–ค ๊ฐ’์ด export ๋˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

if (Math.random()) {
    exports.baz = ···;
}

 

 

๋ฐ˜๋ฉด ESM์ด ์ •์  ๋ชจ๋“ˆ์˜ ์ง€์›ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ์žฅ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

1. tree shaking (๋ฒˆ๋“ค๋ง ์ค‘ ์ฃฝ์€ ์ฝ”๋“œ ์ œ๊ฑฐ)

 

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์—์„œ ๋ชจ๋“ˆ์€ ์ฃผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ธ๋“ค๋ง๋œ๋‹ค :

- ๊ฐœ๋ฐœ ๋„์ค‘ ์•„์ฃผ ๋งŽ๊ณ  ์ฃผ๋กœ ์ž‘์€ ๋ชจ๋“ˆ๋กœ ์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋œ๋‹ค.

- ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด์„œ ์ด ๋ชจ๋“ˆ๋“ค์€ ์ ๊ณ , ์ƒ๋Œ€์ ์œผ๋กœ ํฐ ํŒŒ์ผ๋“ค๋กœ ๋ฒˆ๋“ค๋ง ๋œ๋‹ค. 

 

๋ฒˆ๋“ค๋ง์€ ์™œ ํ• ๊นŒ?

 1. ๋ชจ๋“  ๋ชจ๋“ˆ์„ ๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ์ผ๋“ค์„ ์ฐพ๊ธฐ ์œ„ํ•œ ์ˆ˜๊ณ ๋ฅผ ๋œ ์ˆ˜ ์žˆ๋‹ค. โžก ํŒŒ์ผ ์š”์ฒญ ๋น„์šฉ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋†’์€ HTTP/1์—์„œ ์ค‘์š”, HTTP/2์—์„œ๋Š” ํ•ด๊ฒฐ

 2. ๋ฒˆ๋“ค๋ง ๋œ ํŒŒ์ผ์„ ์••์ถ•ํ•˜๋Š” ๊ฒƒ์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ์„ ์••์ถ•ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํšจ์œจ์ ์ด๋‹ค. 

 3. ๋ฒˆ๋“ค๋ง ๋„์ค‘ ์‚ฌ์šฉ๋˜์ง€ ์•Š์€ export๋Š” ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๊ณ  ์šฉ๋Ÿ‰์„ ์ƒ๋‹นํžˆ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. โžก ์ •์  ๊ตฌ์กฐ์˜ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์—์„œ๋งŒ ์ง€์›

 

2. compact ๋ฒˆ๋“ค๋ง, ์ปค์Šคํ…€ ๋ฒˆ๋“ค๋ง ํ˜•์‹ ์—†์Œ

Rollup ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ์ค‘๋ณต๋œ ๋ณ€์ˆ˜๋ช…์„ ๋ณ€๊ฒฝํ•˜๊ณ , ESM์„ ํšจ์œจ์ ์œผ๋กœ ํ•˜๋‚˜์˜ ์Šค์ฝ”ํ”„๋กœ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ๋ณด์—ฌ์คฌ๋‹ค.

์ด๋Š” ์ •์  ๊ตฌ์กฐ๋ฅผ ์ง€๋…”๊ธฐ ๋•Œ๋ฌธ์— ๋ฒˆ๋“ค ํฌ๋งท์ด ์กฐ๊ฑด๋ถ€์ ์œผ๋กœ ๋ชจ๋“ˆ์ด ๋กœ๋“œ๋˜๋Š” ์ƒํ™ฉ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ณ ,

์ฝ๊ธฐ-์ „์šฉ export ๊ฐ’์„ import ํ•ด์˜จ๋‹ค๋Š” ์ ์—์„œ export๋ฅผ ๋ณต์‚ฌํ•˜์ง€ ์•Š์•„์„œ ์ง์ ‘ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋‹ค์Œ ์˜ˆ์—์„œ Rollup์ด ๋ฒˆ๋“ค๋ง ๊ณผ์ •์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ export๋ฅผ tree shaking ํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ž.

 

๐Ÿ‘ฅ ๋ฒˆ๋“ค๋ง ์ด์ „

// lib.js
export function foo() {}
export function bar() {}

// main.js
import {foo} from './lib.js';
console.log(foo());

 

๐Ÿ‘ค ๋ฒˆ๋“ค๋ง ์ดํ›„ : ์‚ฌ์šฉ๋˜์ง€ ์•Š์€ export bar๋Š” ์ œ๊ฑฐ๋˜์—ˆ๋‹ค.

function foo() {}

console.log(foo());

 

3. import lookup์ด ๋” ๋น ๋ฅด๋‹ค.

 

์ด์ „์— ๋‹ค๋ฃจ์—ˆ๋“ฏ์ด, CJS๋กœ ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ  require๋กœ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋ฉด object์„ ๋ฐ˜ํ™˜๋ฐ›๋Š”๋‹ค.

var lib = require('lib');
lib.someFunc(); // property lookup

 

๋”ฐ๋ผ์„œ ๊ฐ’์˜ property์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” property lookup์„ ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๋™์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋Š๋ฆฌ๋‹ค.

๋ฐ˜๋ฉด์— ESM๋กœ ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ import ํ•ด์˜ค๋Š” ๊ฒฝ์šฐ ์ •์ ์œผ๋กœ ๋ชจ๋“  ์ฝ˜ํ…์ธ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ณ  ์ตœ์ ํ™”๋œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

import * as lib from 'lib';
lib.someFunc(); // statically resolved

 

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ESM๋Š” ๋ณ€์ˆ˜ ์ฒดํฌ, macro ํ˜น์€ ํƒ€์ž… ์ ์šฉ์— ์นœํ™”์ ์ด๋‹ค๋Š” ์žฅ์ ๋„ ์ง€๋…”๋‹ค.

๐Ÿฑ TAKEAWAYS

๋ชจ๋“ˆ ์‹œ์Šคํ…œ์—๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ CJS์™€ ESM ๊ฐ€ ์žˆ๋‹ค. 
CJS๋Š” require์™€ module.exports๋กœ, ESM ์€ import๊ณผ export์œผ๋กœ ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๊ณ  ๋‚ด๋ณด๋‚ธ๋‹ค.
ESM์ด CJS์— ๋น„ํ•ด ์ง€๋‹Œ ์ด์ ๋“ค์ด ์—ฌ๋Ÿฟ ์žˆ๋Š”๋ฐ, ์ด ์ค‘์— tree shaking๊ณผ ์ˆœํ™˜ dependency ์ง€์›์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ๊ผฝ์„ ์ˆ˜ ์žˆ๋‹ค.
์ด๋Š” ESM์ด ์ •์  ๊ตฌ์กฐ๋กœ ๋Ÿฐํƒ€์ž„ ์ด์ „์— import๊ณผ export๋ฅผ ์•Œ ์ˆ˜ ์žˆ์–ด, ์ฃฝ์€ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์šฉ์ดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ESM์€ export์˜ ๋ณต์‚ฌ๋ณธ ๊ฐ์ฒด๋ฅผ import ํ•˜๋Š” CJS์™€ ๋‹ฌ๋ฆฌ,
export ๊ฐ’์˜ ์ฝ๊ธฐ ์ „์šฉ LIVE ๊ฐ’์„ import ํ•œ๋‹ค๋Š” ์ ์—์„œ ์ž๋™์ ์œผ๋กœ ์ˆœํ™˜ dependency๋ฅผ ์ง€์›ํ•ด ์ค€๋‹ค๋Š” ์ ์—์„œ ์žฅ์ ์„ ์ง€๋‹ˆ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ปTMI

๊ธ€์ด ๊ธธ์–ด์งˆ ๊ฑฐ ๊ฐ™์•„์„œ ๋ฒˆ๋“ค๋ง ๊ด€๋ จ์€ ๋‹ค์Œ์— ๋‹ค๋ค„์•ผ ํ•  ๊ฑฐ ๊ฐ™๋‹ค.

๋ชจ๋“ˆ ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ์ž˜ ๋ชจ๋ฅด๊ณ  ๋„˜์–ด๊ฐ„ ๋ถ€๋ถ„์„ ๋ณด๊ณ  ๊ฐˆ ์ˆ˜ ์žˆ์—ˆ๋˜ ์‹œ๊ฐ„์ด์—ˆ๋‹ค.

 

๐Ÿ“š References

https://www.freecodecamp.org/news/anatomy-of-js-module-systems-and-building-libraries-fadcd8dbd0e/

 

Learn the basics of the JavaScript module system and build your own library

by Kamlesh Chandnani Learn the basics of the JavaScript module system and build your own library Lately we all have been hearing a lot about “JavaScript Modules”. Everyone is likely wondering what to do with them, and how do they even play a vital role

www.freecodecamp.org

https://exploringjs.com/es6/ch_modules.html#static-module-structure

 

16. Modules

16. Modules 16.1. Overview 16.1.1. Multiple named exports 16.1.2. Single default export 16.1.3. Browsers: scripts versus modules 16.2. Modules in JavaScript 16.2.1. ECMAScript 5 module systems 16.2.2. ECMAScript 6 modules 16.3. The basics of ES6 modules 16

exploringjs.com