ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ชจ๋“ˆ์˜ ์ผ๋ฐ˜์  ์˜๋ฏธ

๋ชจ๋“ˆ(module)์ด๋ž€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐœ๋ณ„์  ์š”์†Œ๋กœ์„œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“ˆ์€ ๊ธฐ๋Šฅ์„ ๊ธฐ์ค€์œผ๋กœ ํŒŒ์ผ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌ
  • ๋ชจ๋“ˆ์ด ์„ฑ๋ฆฝํ•˜๋ ค๋ฉด ๋ชจ๋“ˆ์€ ์ž์‹ ๋งŒ์˜ ํŒŒ์ผ ์Šค์ฝ”ํ”„(๋ชจ๋“ˆ ์Šค์ฝ”ํ”„)๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • ๋ชจ๋“ˆ์˜ ์ž์‚ฐ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์บก์Šํ™”๋˜์–ด ๋น„๊ณต๊ฐœ ์ƒํƒœ๋กœ ๊ฐœ๋ณ„์  ์กด์žฌ๋กœ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ถ„๋ฆฌ๋˜์–ด ์กด์žฌ
  • ๊ณต๊ฐœ๊ฐ€ ํ•„์š”ํ•œ ์ž์‚ฐ์— ํ•œ์ •ํ•˜์—ฌ export๋ฅผ ํ†ตํ•ด ๋ช…์‹œ์ ์œผ๋กœ ์„ ํƒ์  ๊ณต๊ฐœ๊ฐ€ ๊ฐ€๋Šฅ
  • ๋ชจ๋“ˆ ์‚ฌ์šฉ์ž๋Š” ๋ชจ๋“ˆ์ด ๊ณต๊ฐœํ•œ ์ž์‚ฐ ์ค‘ ์ผ๋ถ€ ๋˜๋Š” ์ „์ฒด๋ฅผ ์„ ํƒํ•ด import๋กœ ์ž์‹ ์˜ ์Šค์ฝ”ํ”„ ๋‚ด๋กœ ๋ถˆ๋Ÿฌ๋“ค์—ฌ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

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


๋”ฐ๋ผ์„œ ๋ชจ๋“ˆ์€ ์ฝ”๋“œ์˜ ๋‹จ์œ„๋ฅผ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , ์žฌ์‚ฌ์šฉ์„ฑ์ด ์ข‹์•„์„œ ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋ชจ๋“ˆ

์›นํŽ˜์ด์ง€์˜ ๋‹จ์ˆœํ•œ ๋ณด์กฐ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ œํ•œ์ ์ธ ์šฉ๋„์˜ ๋ชฉ์ ์œผ๋กœ ํƒœ์–ด๋‚œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํƒœ์ƒ์  ํ•œ๊ณ„๋กœ ์ธํ•ด

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ script ํƒœ๊ทธ๋กœ ๋กœ๋“œํ•ด๋„ ๊ฒฐ๊ตญ ๋ชจ๋“  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์€ ํ•˜๋‚˜์˜ ์ „์—ญ์„ ๊ณต์œ 
  • ์ „์—ญ ๋ณ€์ˆ˜๊ฐ€ ์ค‘๋ณต๋˜๋Š” ๋“ฑ์˜ ๋ฌธ์ œ๋กœ ์ธํ•ด ๋ชจ๋“ˆ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์Œ

 

๋”ฐ๋ผ์„œ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” CommonJS์™€ AMD(Asynchronous Module Definition)๋ฅผ ๊ตฌํ˜„ํ•œ ๋ชจ๋“ˆ ๋กœ๋” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๋Œ€ํ‘œ์ ์œผ๋กœ Node.js๋Š” ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ธ CommonJS ์‚ฌ์–‘์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์–ด (๋…์ž์ ์œผ๋กœ ์ง„ํ™”๋ฅผ ๊ฑฐ์ณ 100% ๋™์ผ X) ECMAScript ํ‘œ์ค€ ์‚ฌ์–‘์€ ์•„๋‹ˆ์ง€๋งŒ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Node.js ํ™˜๊ฒฝ์—์„œ๋Š” ํŒŒ์ผ๋ณ„๋กœ ๋…๋ฆฝ์ ์ธ ํŒŒ์ผ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

 


ES6 ๋ชจ๋“ˆ(ESM)

ES6์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ๋™์ž‘ํ•˜๋Š” ๋ชจ๋“ˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ IE๋ฅผ ์ œ์™ธํ•œ ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ES6 ๋ชจ๋“ˆ(ESM)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

<script type="module" src="app.mjs"></script>
  • script ํƒœ๊ทธ์— type = "module" ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋กœ๋“œ๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์€ ๋ชจ๋“ˆ๋กœ์„œ ๋™์ž‘
  • ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์ด ์•„๋‹Œ ESM์ž„์„ ๋ช…ํ™•ํžˆ ํ•˜๊ธฐ ์œ„ํ•ด mjs ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ
  • ํด๋ž˜์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ strict mode๊ฐ€ ์ ์šฉ

 

๋ชจ๋“ˆ ์Šค์ฝ”ํ”„

ESM์€ ๋…์ž์ ์ธ ๋ชจ๋“ˆ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. 

 

๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด 2๊ฐœ์˜ mjsํŒŒ์ผ์ด ์กด์žฌํ•  ๋•Œ ESM์˜ ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<!DOCTYPE html>
<html>
<body>
  <script type="module" src="foo.mjs"></script>
  <script type="module" src="bar.mjs"></script>
</body>
</html>

 

 

๋ชจ๋“ˆ ๋‚ด์—์„œ var ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฉฐ window ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋„ ์•„๋‹ˆ๋‹ค.

 

// foo.mjs
// x ๋ณ€์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฉฐ window ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋„ ์•„๋‹ˆ๋‹ค.
var x = 'foo';
console.log(x); // foo
console.log(window.x); // undefined

// bar.mjs
// x ๋ณ€์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฉฐ window ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋„ ์•„๋‹ˆ๋‹ค.
// foo.mjs์—์„œ ์„ ์–ธํ•œ x ๋ณ€์ˆ˜์™€ ์Šค์ฝ”ํ”„๊ฐ€ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋‹ค.
var x = 'bar';
console.log(x); // bar
console.log(window.x); // undefined

 

 

๋ชจ๋“ˆ ๋‚ด์—์„œ ์„ ์–ธํ•œ ์‹๋ณ„์ž๋Š” ๋ชจ๋“ˆ ์™ธ๋ถ€(๋ชจ๋“ˆ ์Šค์ฝ”ํ”„๊ฐ€ ๋‹ค๋ฆ„)์—์„œ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค.

 

// foo.mjs
const x = 'foo';
console.log(x); // foo

// bar.mjs
console.log(x); // ReferenceError: x is not defined

 

export ํ‚ค์›Œ๋“œ

๋ชจ๋“ˆ ๋‚ด๋ถ€์—์„œ ์„ ์–ธํ•œ ์‹๋ณ„์ž๋ฅผ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•˜์—ฌ ๋‹ค๋ฅธ ๋ชจ๋“ˆ๋“ค์ด ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด export ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. export ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์„ ์–ธ๋ฌธ ์•ž์— export ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ํด๋ž˜์Šค ๋“ฑ ๋ชจ๋“  ์‹๋ณ„์ž๋ฅผ export ํ•  ์ˆ˜ ์žˆ์Œ
  • exportํ•  ๋Œ€์ƒ์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ํ•œ ๋ฒˆ์— export ํ•  ์ˆ˜ ์žˆ์Œ
// export ๋ฐฉ๋ฒ• 1
// lib.mjs
// ๋ณ€์ˆ˜์˜ ๊ณต๊ฐœ
export const pi = Math.PI;

// ํ•จ์ˆ˜์˜ ๊ณต๊ฐœ
export function square(x) {
  return x * x;
}

// ํด๋ž˜์Šค์˜ ๊ณต๊ฐœ
export class Person {
  constructor(name) {
    this.name = name;
  }
}
// export ๋ฐฉ๋ฒ• 2
// lib.mjs
const pi = Math.PI;

function square(x) {
  return x * x;
}

class Person {
  constructor(name) {
    this.name = name;
  }
}

// ๋ณ€์ˆ˜, ํ•จ์ˆ˜ ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ๊ณต๊ฐœ
export { pi, square, Person };

 

import ํ‚ค์›Œ๋“œ

๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ๊ณต๊ฐœ(export)ํ•œ ์‹๋ณ„์ž๋ฅผ ์ž์‹ ์˜ ๋ชจ๋“ˆ ์Šค์ฝ”ํ”„ ๋‚ด๋ถ€๋กœ ๋กœ๋“œํ•˜๋ ค๋ฉด import ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. import ํ•˜์—ฌ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์ด exportํ•œ ์‹๋ณ„์ž ์ด๋ฆ„์œผ๋กœ importํ•ด์•ผ ํ•˜๋ฉฐ ESM์˜ ๊ฒฝ์šฐ ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์—†๋‹ค.

 

// app.mjs
// ๊ฐ™์€ ํด๋” ๋‚ด์˜ lib.mjs ๋ชจ๋“ˆ์ด exportํ•œ ์‹๋ณ„์ž ์ด๋ฆ„์œผ๋กœ importํ•œ๋‹ค.
// ESM์˜ ๊ฒฝ์šฐ ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์—†๋‹ค.
import { pi, square, Person } from './lib.mjs';

console.log(pi);         // 3.141592653589793
console.log(square(10)); // 100
console.log(new Person('Lee')); // Person { name: 'Lee' }
<!DOCTYPE html>
<html>
<body>
  <script type="module" src="app.mjs"></script>
</body>
</html>
  • ์œ„ ์˜ˆ์ œ์˜ app.mjs๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ง„์ž…์ ์ด๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ script ํƒœ๊ทธ๋กœ ๋กœ๋“œํ•ด์•ผ ํ•˜์ง€๋งŒ lib.mjs๋Š” app.mjs์˜ import ๋ฌธ์— ์˜ํ•ด ๋กœ๋“œ๋˜๋Š” ์˜์กด์„ฑ์ด๊ธฐ ๋•Œ๋ฌธ์— script ํƒœ๊ทธ๋กœ ๋กœ๋“œํ•˜์ง€ ์•Š์•„๋„ ๋จ

 

๋ชจ๋“ˆ์ด exportํ•œ ์‹๋ณ„์ž ์ด๋ฆ„์„ ์ผ์ผ์ด ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ํ•˜๋‚˜์˜ ์ด๋ฆ„์œผ๋กœ ํ•œ ๋ฒˆ์— import ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

  • import๋˜๋Š” ์‹๋ณ„์ž๋Š” as ๋’ค์— ์ง€์ •ํ•œ ์ด๋ฆ„์˜ ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋กœ ํ• ๋‹น๋จ
// app.mjs
// lib.mjs ๋ชจ๋“ˆ์ด exportํ•œ ๋ชจ๋“  ์‹๋ณ„์ž๋ฅผ lib ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋กœ ๋ชจ์•„ importํ•œ๋‹ค.
import * as lib from './lib.mjs';

console.log(lib.pi);         // 3.141592653589793
console.log(lib.square(10)); // 100
console.log(new lib.Person('Lee')); // Person { name: 'Lee' }

 

๋ชจ๋“ˆ์ด exportํ•œ ์‹๋ณ„์ž ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜์—ฌ importํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

// app.mjs
// lib.mjs ๋ชจ๋“ˆ์ด exportํ•œ ์‹๋ณ„์ž ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜์—ฌ importํ•œ๋‹ค.
import { pi as PI, square as sq, Person as P } from './lib.mjs';

console.log(PI);    // 3.141592653589793
console.log(sq(2)); // 4
console.log(new P('Kim')); // Person { name: 'Kim' }

 

 

๋ชจ๋“ˆ์—์„œ ํ•˜๋‚˜์˜ ๊ฐ’๋งŒ export ํ•œ๋‹ค๋ฉด default ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • default ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฆ„ ์—†์ด ํ•˜๋‚˜์˜ ๊ฐ’์„ export
  • default ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ var, let, const ํ‚ค์›Œ๋“œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
  • default ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ exportํ•œ ๋ชจ๋“ˆ์€ {}์—†์ด ์ž„์˜์˜ ์ด๋ฆ„์œผ๋กœ importํ•จ
// lib.mjs
export default x => x * x;

// lib.mjs
export default const foo = () => {};
// => SyntaxError: Unexpected token 'const'
// export default () => {};

// app.mjs
import square from './lib.mjs';

console.log(square(3)); // 9

[์ถœ์ฒ˜] ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive

https://wikibook.co.kr/mjs/

 

๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ

269๊ฐœ์˜ ๊ทธ๋ฆผ๊ณผ ์›๋ฆฌ๋ฅผ ํŒŒํ—ค์น˜๋Š” ์„ค๋ช…์œผ๋กœ ‘์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ’๋ฅผ ์ดํ•ดํ•˜์ž! ์›นํŽ˜์ด์ง€์˜ ๋‹จ์ˆœํ•œ ๋ณด์กฐ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ œํ•œ์ ์ธ ์šฉ๋„๋กœ ํƒœ์–ด๋‚œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ณผ๋„

wikibook.co.kr