Understanding ES6 Modules - Lee-hyuna/33-js-concepts-kr GitHub Wiki

ES6 Modules์˜ ์ดํ•ด

์›๋ฌธ : https://www.sitepoint.com/understanding-es6-modules/#usinges6modulesinnodejs

์ด ๊ธ€์€ ES6 Module์„ ํƒ๊ตฌํ•˜์—ฌ, ES6 Module์ด ์–ด๋–ป๊ฒŒ ์˜ค๋Š˜๋‚  ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ์˜ ๋„์›€์„ ๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด๋Š” ํ•œ ํŒŒ์ผ์— ์„ ์–ธ๋œ ๊ธฐ๋Šฅ์„ ๋‹ค๋ฅธ ํŒŒ์ผ์— ํฌํ•จ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ธ Module ๊ฐœ๋…์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ๊ฐ์˜ ์—ญํ• ๋“ค๊ณผ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์บก์Šํ™”๋œ ์ฝ”๋“œ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๋งŒ๋“ค์–ด๋ƒ…๋‹ˆ๋‹ค.
(Typically, a developer creates an encapsulated library of code responsible for handling related tasks. > ์˜์—ญ) ์ด๋“ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ˜น์€ ๋‹ค๋ฅธ Module์— ์˜ํ•ด ์ฐธ์กฐ๋˜์–ด์ง‘๋‹ˆ๋‹ค.

์žฅ์  :

  1. ์ฝ”๋“œ๋Š” ์ž‘์€ ํŒŒ์ผ๋“ค๋กœ ๋ถ„ํ• ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์–ด๋Š ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์–ด๋””๋“ ์ง€) ๋™์ผํ•œ Module์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์ด์ƒ์ ์œผ๋กœ, Module๋“ค์€ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์— ์˜ํ•ด ๊ฒ€์ฆ๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด Module๋“ค์˜ ๊ธฐ๋Šฅ์ด ์ž…์ฆ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.(์ผ๋ถ€ ์˜์—ญ : works์„ ๊ธฐ๋Šฅ์œผ๋กœ)
  4. Module์„ ์ฐธ์กฐํ•˜๋Š” ์ฝ”๋“œ๋Š” ์˜์กด์„ฑ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. Module ํŒŒ์ผ์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์ด๋™๋˜๋ฉด ์ฆ‰์‹œ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
  5. Module ์ฝ”๋“œ๋Š” (๋ณดํ†ต) ๋„ค์ด๋ฐ ์ค‘๋ณต์„ ์ค„์ด๋Š”๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. module1์—์„œ์˜ ํ•จ์ˆ˜ x()๋Š” module2์—์„œ ํ•จ์ˆ˜์™€ ์ถฉ๋Œ์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ๊ฐ™์€ ์˜ต์…˜๋“ค์ด ์‚ฌ์šฉ๋˜์–ด์„œ module1.x() ์™€ module2.x()์ด ๋ฉ๋‹ˆ๋‹ค.

Javascript์—์„œ Module์€ ์–ด๋””์— ์žˆ์Šต๋‹ˆ๊นŒ?

๋ช‡ ๋…„ ์ „์— ์›น ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•˜๋Š” ๋ˆ„๊ตฐ๊ฐ€๋Š” Javascript์— Module ๊ฐœ๋…์ด ์—†๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฐœ๊ฒฌํ•œ ๊ฒƒ์— ๋Œ€ํ•ด ์ถฉ๊ฒฉ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ Javascript ํŒŒ์ผ์„ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์ง์ ‘ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ํฌํ•จํ•˜๋Š” ๊ฒƒ์„ ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์ค‘ HTML <script> ํƒœ๊ทธ

HTML์€ ๋‹ค์ค‘ <script>ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ Javascript ํŒŒ์ผ๋“ค์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ผ๋ถ€ ์˜์—ญ)

<script src="lib1.js"></script>
<script src="lib2.js"></script>
<script src="core.js"></script>
<script>
console.log('inline code');
</script>

average web page in 2018 uses 25 separate scripts์€ ์•„์ง ์‹ค์šฉ์ ์ธ ์†”๋ฃจ์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค.

๊ฐ๊ฐ ์Šคํฌ๋ฆฝํŠธ๋Š” ํŽ˜์ด์ง€ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์ƒˆ๋กœ์šด HTTP ์š”์ฒญ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

HTTP/2๋Š” ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋Š ์ •๋„ ์ค„์—ฌ์ฃผ์ง€๋งŒ , CDN๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ์ฐธ์กฐ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ์—๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋Š” ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๋” ์ด์ƒ์˜ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๊ด€๋ฆฌ๋Š” ์ˆ˜๋™์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ ๋งŒ์•ฝ lib1.js๊ฐ€ lib2.js ์˜ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ–ˆ๋‹ค๋ฉด, ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Javascript ์ฒ˜๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋กœ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ ์ ˆํ•˜๊ฒŒ module patterns์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐ Javascript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ธ€๋กœ๋ฒŒ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์•…๋ช…์ด ๋†’์•˜์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ์™€ ์—ฐ๊ฒฐ

๋‹ค์ค‘์˜ <script> ํƒœ๊ทธ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ํ•ด๊ฒฐ์ฑ…์€ ๋ชจ๋“  Javascript ํŒŒ์ผ์„ ํ•˜๋‚˜์˜ ํฐ ํŒŒ์ผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋กœ ์ธํ•ด ์ผ๋ถ€ ์„ฑ๋Šฅ ๋ฐ ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€๋งŒ ์ˆ˜๋™ ๊ตฌ์ถ• ๋ฐ ํ…Œ์ŠคํŠธ ๋‹จ๊ณ„๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Module ๋กœ๋”

RequireJS ๊ทธ๋ฆฌ๊ณ  SystemJS์™€ ๊ฐ™์€ ์‹œ์Šคํ…œ์€ ๋Ÿฐํƒ€์ž„์— ๋‹ค๋ฅธ Javascript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋“œํ•˜๊ณ , ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— Ajax ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์€ ๋„์›€์ด ๋˜์ง€๋งŒ <script> ํƒœ๊ทธ๋ฅผ ๋” ํฐ ์ฝ”๋“œ ๋ฒ ์ด์Šค ๋˜๋Š” ์‚ฌ์ดํŠธ์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Module ๋ฒˆ๋“ค๋Ÿฌ, ์ „์ฒ˜๋ฆฌ ๋ฐ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ

๋ฒˆ๋“ค๋Ÿฌ๋Š” ์ปดํŒŒ์ผ ๋‹จ๊ณ„๋ฅผ ๋„์ž…ํ•˜๋ฏ€๋กœ ๋นŒ๋“œ ์‹œ์— Javascript ์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ์˜์กด์„ฑ์„ ํฌํ•จํ•˜๋„๋ก ์ฒ˜๋ฆฌ๋˜๊ณ  ์–ด๋Š ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ˜ธํ™˜์ด ๋˜๋„๋ก ํ•˜๋‚˜๋กœ ์—ฐ๊ฒฐ๋œ ES5 ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.(Code is processed to include dependencies and produce a single ES5 cross-browser compatible concatenated file.> ์˜์—ญ). ์ธ๊ธฐ ์žˆ๋Š” ์˜ต์…˜์œผ๋กœ๋Š” Babel, Browserify, webpack ๋ฐ Grunt and Gulp์™€ ๊ฐ™์€ task runner๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Javascript ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋Š” ์•ฝ๊ฐ„์˜ ๋…ธ๋ ฅ์„ ํ•ด์•ผ ํ•˜์ง€๋งŒ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ฒ˜๋ฆฌ๊ฐ€ ์ž๋™ํ™”๋˜์–ด ์žˆ์–ด์„œ ์‚ฌ๋žŒ์ด ์‹ค์ˆ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ์ž‘์Šต๋‹ˆ๋‹ค.
  • ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๋Š” ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ , ๋””๋ฒ„๊น… ๋ช…๋ น๋“ค์„ ์ œ๊ฑฐํ•˜๋ฉฐ, ์ตœ์ข… ๊ฒฐ๊ณผ์˜ ํŒŒ์ผ์„ ์••์ถ•ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (minify => ์••์ถ•์œผ๋กœ ์˜์—ญ)
  • TypeScript ๋˜๋Š”CoffeeScript์™€ ๊ฐ™์€ ๋Œ€์ฒด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ES6 Module

์œ„์˜ ์˜ต์…˜์€ ๋‹ค์–‘ํ•œ competing module definition ํ˜•์‹์ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„๋ฆฌ ์ฑ„ํƒ๋œ ๋ฌธ๋ฒ•์€ ์ด์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • CommonJS โ€” Node.js์—์„œ module.exports์™€ require๋ฌธ๋ฒ• ์‚ฌ์šฉ
  • Asynchronous Module Definition (AMD)
  • Universal Module Definition (UMD).

๋”ฐ๋ผ์„œ ๋‹จ์ผ, ๋„ค์ดํ‹ฐ๋ธŒ Module ํ‘œ์ค€์€ ES6์—์„œ ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ES6 Module์˜ ๋‚ด๋ถ€๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ private์ด๊ณ , strict ๋ชจ๋“œ์—์„œ ์‹คํ–‰์ด ๋ฉ๋‹ˆ๋‹ค. ('use strict' ์ฝ”๋“œ๋ฅผ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

public ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ๊ทธ๋ฆฌ๊ณ  ํด๋ž˜์Šค๋Š” export์„ ์‚ฌ์šฉํ•ด์„œ Module์— ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค. (์ผ๋ถ€ ์˜์—ญ)

์˜ˆ๋ฅผ ๋“ค์–ด

// lib.js
export const PI = 3.1415926;

export function sum(...args) {
  log('sum', args);
  return args.reduce((num, tot) => tot + num);
}

export function mult(...args) {
  log('mult', args);
  return args.reduce((num, tot) => tot * num);
}

// private function
function log(...msg) {
  console.log(...msg);
}

ํ•˜๋‚˜์˜export๋ฌธ์œผ๋กœ๋„ ์‚ฌ์šฉํ•˜์—ฌ Module๋กœ ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ํด๋ž˜์Šค๋“ค์„ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ผ๋ถ€ ์˜์—ญ)

์˜ˆ๋ฅผ ๋“ค์–ด

// lib.js
const PI = 3.1415926;

function sum(...args) {
  log('sum', args);
  return args.reduce((num, tot) => tot + num);
}

function mult(...args) {
  log('mult', args);
  return args.reduce((num, tot) => tot * num);
}

// private function
function log(...msg) {
  console.log(...msg);
}

export { PI, sum, mult };

import๋Š” Module์—์„œ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๋‚˜ Module๋กœ ๋‹ค๋ฅธ ๋Œ€์ƒ์„ ๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

// main.js
import { sum } from './lib.js';

console.log( sum(1,2,3,4) ); // 10

์ด์™€ ๊ฐ™์€ ์ผ€์ด์Šค๋Š” lib.js๋Š” main.js์™€ ๊ฐ™์€ ํด๋”์— ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ๊ฒฝ๋กœ๋Š” ์ ˆ๋Œ€ ํŒŒ์ผ ์ฐธ์กฐ(/๋กœ ์‹œ์ž‘), ์ƒ๋Œ€ ํŒŒ์ผ ์ฐธ์กฐ (./ ๋˜๋Š” ../) ๋˜๋Š” ์ „์ฒด URL์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ผ๋ถ€ ์˜์—ญ)

ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋Œ€์ƒ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { sum, mult } from './lib.js';

console.log( sum(1,2,3,4) );  // 10
console.log( mult(1,2,3,4) ); // 24

import๋Š” ๋ณ„์นญ(aliase)์„ ์‚ฌ์šฉํ•˜์—ฌ ๋„ค์ด๋ฐ ์ถฉ๋Œ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(์ผ๋ถ€ ์˜์—ญ)

import { sum as addAll, mult as multiplyAll } from './lib.js';

console.log( addAll(1,2,3,4) );      // 10
console.log( multiplyAll(1,2,3,4) ); // 24

๋งˆ์ง€๋ง‰์œผ๋กœ, ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•จ์œผ๋กœ์จ ๋ชจ๋“  ๊ณต์šฉ์˜ ๋Œ€์ƒ๋“ค์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import * as lib from './lib.js';

console.log( lib.PI );            // 3.1415926
console.log( lib.add(1,2,3,4) );  // 10
console.log( lib.mult(1,2,3,4) ); // 24

๋ธŒ๋ผ์šฐ์ ธ์—์„œ ES6 Module์„ ์‚ฌ์šฉ ํ•˜๋Š” ๋ฐฉ๋ฒ•

ํ•ด๋‹น ๊ธ€์„ ์ž‘์„ฑ ๋‹น์‹œ์— ES6 Module์˜ ์ง€์›๋ฒ”์œ„๋Š” ํฌ๋กฌ ๊ธฐ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ ธ(v63+), Safari 11+, Edge 16+, Firefox 60(v58+์˜ about:config ํ”Œ๋ž˜๊ทธ ๋’ค์— ์žˆ์Œ) ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

Module์„ ์‚ฌ์šฉํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋Š” <script> ํƒœ๊ทธ์— type="module" ์†์„ฑ์„ ์„ค์ •ํ•˜์—ฌ ๋กœ๋“œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์ž๋ฉด,

<script type="module" src="./main.js"></script>

๋˜๋Š” ์ธ๋ผ์ธ์œผ๋กœ

<script type="module">
  import { something } from './somewhere.js';
  // ...
</script>

Module์€ ํŽ˜์ด์ง€ ๋˜๋Š” ๋‹ค๋ฅธ Module์—์„œ ์ฐธ์กฐ๋˜๋Š” Module์—์„œ ํšŸ์ˆ˜์— ์ƒ๊ด€์—†์ด ํ•œ ๋ฒˆ ํŒŒ์‹ฑ์ด ๋ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„์—์„œ์˜ ๊ณ ๋ ค์‚ฌํ•ญ

Module๋Š” MIME ํƒ€์ž…์œผ๋กœ application/javascript์ด ํ•จ๊ป˜ ์ œ๊ณต๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋ฒ„๋Š” ์ž๋™์œผ๋กœ MIME ํƒ€์ž…์œผ๋กœ application/javascript์ด ํ•จ๊ป˜ ์ œ๊ณตํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ, ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ์Šคํฌ๋ฆฝํŠธ๋‚˜ .mjs ํŒŒ์ผ์—์„œ๋Š” ์ฃผ์˜ํ•˜์„ธ์š”. (ํ•˜๋‹จ์˜ Node.js ์„น์…˜์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

์ผ๋ฐ˜์ ์œผ๋กœ <script> ํƒœ๊ทธ๊ฐ€ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ fetch ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, Module์€ CORS์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ fetch ๋˜์–ด์ง‘๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ Module์€ Access-Control-Allow-Origin: *์™€ ๊ฐ™์€ ์ ์ ˆํ•œ HTTP ํ—ค๋”๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋์œผ๋กœ, Module์€ crossorigin="use-credentials" ์†์„ฑ์ด <script>์— ์ถ”๊ฐ€๋˜๊ณ  ์‘๋‹ต์— Access-Control-Allow-Credentials: true ํ—ค๋”๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ฟ ํ‚ค๋‚˜ ๋‹ค๋ฅธ ํ—ค๋” ์ž๊ฒฉ ์ฆ๋ช…์„ ๋ณด๋‚ด์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Module ์‹คํ–‰ ์ง€์—ฐ

<script defer> ์†์„ฑ์€ ๋ฌธ์„œ์— ๋กœ๋“œ๋˜๊ณ  ํŒŒ์‹ฑ ๋  ๋•Œ๊นŒ์ง€ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์„ ์ง€์—ฐ์‹œํ‚ต๋‹ˆ๋‹ค. ์ธ๋ผ์ธ์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํฌํ•จํ•œ Module์€ ๊ธฐ๋ณธ์ ์œผ๋กœ defer์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์ž๋ฉด

<!-- runs SECOND -->
<script type="module">
  // do something...
</script>

<!-- runs THIRD -->
<script defer src="c.js"></script>

<!-- runs FIRST -->
<script src="a.js"></script>

<!-- runs FOURTH -->
<script type="module" src="b.js"></script>

Module Fallback

Module ์ง€์›์ด ์—†๋Š” ๋ธŒ๋ผ์šฐ์ €๋Š” type="module" ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. fallback ์Šคํฌ๋ฆฝํŠธ๋Š” nomodule ์†์„ฑ์œผ๋กœ Module ํ˜ธํ™˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (A fallback script can be provided with a nomodule attribute which module-compatible browsers ignore. > ์˜์—ญ)

์˜ˆ๋ฅผ ๋“ค๋ฉด

<script type="module" src="runs-if-module-supported.js"></script>
<script nomodule src="runs-if-module-not-supported.js"></script>

๋ธŒ๋ผ์šฐ์ €์—์„œ Module์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด?

๋ธŒ๋ผ์šฐ์ € ์ง€์› ๋ฒ”์œ„๋Š” ์ฆ๊ฐ€ํ•˜๊ณ  ์žˆ์ง€๋งŒ ES6 Module๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์•„์ง ์‹œ๊ธฐ์ƒ์กฐ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์จ๋Š” Module ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์–ด๋””์—์„œ๋‚˜ ์ž‘๋™ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Node.js ์—์„œ ES6 Module ์‚ฌ์šฉ

2009๋…„ Node.js๊ฐ€ ์ถœ์‹œ๋˜์—ˆ์„ ๋•Œ Module์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๋Ÿฐํƒ€์ž„์€ ์ƒ์ƒํ•  ์ˆ˜ ์—†์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. CommonJS๊ฐ€ ์ฑ„ํƒ๋˜์—ˆ๋Š”๋ฐ, ์ด๋Š” ๋…ธ๋“œ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์ธ npm์ด ๊ฐœ๋ฐœ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์‹œ์ ๋ถ€ํ„ฐ ์‚ฌ์šฉ๋Ÿ‰์ด ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

CommonJSModule์€ ES2015 Module๊ณผ ์œ ์‚ฌํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ฝ”๋“œํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

module.exports is used rather than export:

// lib.js
const PI = 3.1415926;

function sum(...args) {
  log('sum', args);
  return args.reduce((num, tot) => tot + num);
}

function mult(...args) {
  log('mult', args);
  return args.reduce((num, tot) => tot * num);
}

// private function
function log(...msg) {
  console.log(...msg);
}

module.exports = { PI, sum, mult };

require(import ๋ณด๋‹ค)์€ ์ด ๋ชจ๋“ˆ์„ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ ๋˜๋Š” ๋ชจ๋“ˆ๋กœ ๋Œ์–ด์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

const { sum, mult } = require('./lib.js');

console.log( sum(1,2,3,4) );  // 10
console.log( mult(1,2,3,4) ); // 24

require์€ ๋ชจ๋“  ๋Œ€์ƒ์„ ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const lib = require('./lib.js');

console.log( lib.PI );            // 3.1415926
console.log( lib.add(1,2,3,4) );  // 10
console.log( lib.mult(1,2,3,4) ); // 24

๊ทธ๋ž˜์„œ ES6 Module์€ Node.js์—์„œ ์‰ฝ๊ฒŒ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งž๋‚˜์š”? Er, ์•„๋‹ˆ.

ES6 Module์€ Node.js 9.8.0+ ํ”Œ๋ž˜๊ทธ ๋’ค์— ์žˆ์œผ๋ฉฐ, ์ ์–ด๋„ ๋ฒ„์ „ 10๊นŒ์ง€๋Š” ์™„์ „ํžˆ ๊ตฌํ˜„๋˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. CommonJS์™€ ES6 Module์€ ์œ ์‚ฌํ•œ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๊ทผ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

  • ES6 module์€ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์ข€ ๋” ๋งŽ์€ import๋ฅผ resolveํ•˜๊ธฐ ์œ„ํ•ด ๋ฏธ๋ฆฌ ๊ตฌ๋ฌธ์„ ํŒŒ์‹ฑ ํ•ฉ๋‹ˆ๋‹ค. (ES6 modules are pre-parsed in order to resolve further imports before code is executed. > ์˜์—ญ)

  • CommonJS module์€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ ํ•„์š”์— ๋”ฐ๋ผ ์˜์กด์„ฑ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์˜ˆ์—์„œ๋Š” ์•„๋ฌด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์—†์—ˆ์ง€๋งŒ, ๋‹ค์Œ ES2015 module ์ฝ”๋“œ๋ฅผ ๋ด์ฃผ์„ธ์š”. (์ผ๋ถ€ ์˜์—ญ)

// ES2015 modules

// ---------------------------------
// one.js
console.log('running one.js');
import { hello } from './two.js';
console.log(hello);

// ---------------------------------
// two.js
console.log('running two.js');
export const hello = 'Hello from two.js';

ES2015์˜ ๊ฒฐ๊ณผ ์ฝ”๋“œ

running two.js
running one.js
hello from two.js

CommonJS์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑํ•œ ๋น„์Šทํ•œ ์ฝ”๋“œ

// CommonJS modules

// ---------------------------------
// one.js
console.log('running one.js');
const hello = require('./two.js');
console.log(hello);

// ---------------------------------
// two.js
console.log('running two.js');
module.exports = 'Hello from two.js';

ES2015์˜ ๊ฒฐ๊ณผ ์ฝ”๋“œ

running one.js
running two.js
hello from two.js

์ผ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ES2015 and CommonJS Module์ด ๊ฐ™์€ ํŒŒ์ผ์—์„œ ํ˜ผํ•ฉ๋œ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ๋˜๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Node.js๋Š” ํ™•์žฅ์ž๊ฐ€ .mjs์ธ Module๋งŒ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

.js ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง„ ํŒŒ์ผ์€ CommonJS๋กœ ๊ธฐ๋ณธ ์„ค์ •์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ์„ค์ •์€ ๋ณต์žก์„ฑ์„ ๋งŽ์ด ์ œ๊ฑฐํ•˜๊ณ  ์ฝ”๋“œ ์—๋””ํ„ฐ ๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ linter๋ฅผ ๋•๋Š” ๊ฐ„๋‹จํ•œ ์˜ต์…˜์ž…๋‹ˆ๋‹ค.

Node.js์—์„œ ES6 module์„ ์‚ฌ์šฉ ํ•ด์•ผ ํ•œ๋‹ค๋ฉด?

ES6 module์€ Node.js v10๋ถ€ํ„ฐ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(2018๋…„ 4์›” ์ถœ์‹œ). ๊ธฐ์กด ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณ€ํ™˜ํ•ด๋„ ์žฅ์ ์ด ์—†์œผ๋ฉฐ ์ด์ „ ๋ฒ„์ „์˜ Node.js์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ ES6 module์€ CommonJS์˜ ๋Œ€์•ˆ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ๋ฒ•์€ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋”ฉ๊ณผ ๋™์ผํ•˜๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €๋‚˜ ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” isomorphic Javascript(๋™ํ˜• ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ)์— ๋Œ€ํ•œ ์‰ฌ์šด ๊ฒฝ๋กœ(์ ‘๊ทผ ๋ฐฉ๋ฒ•)๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (The syntax is identical to client-side coding, and may offer an easier route to isomorphic Javascript, which can run in the either the browser or on a server....์–ด๋–ป๊ฒŒ ๋ฒˆ์—ญํ•ด์•ผํ• ๊นŒ...)

Module Melee(Melee:์˜์–ด ๋œป์œผ๋กœ ํ˜ผ์žก, ๋‚œ์žก, ๋‚œํˆฌ...;)

ํ‘œ์ค€ํ™”๋œ Javascript module ์‹œ์Šคํ…œ์œผ๋กœ ๋˜๊ธฐ๊นŒ์ง€ ์ˆ˜๋…„์ด ๊ฑธ๋ ธ์œผ๋ฉฐ, ๊ตฌํ˜„๊นŒ์ง€ ๋” ์˜ค๋ž˜ ๊ฑธ๋ ธ์ง€๋งŒ, ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 2018๋…„ ์ค‘๋ฐ˜์˜ ๋ชจ๋“  ์ฃผ๋ฅ˜ ๋ธŒ๋ผ์šฐ์ €์™€ Node.js๋Š” ES6 module์„ ์ง€์›ํ•˜์ง€๋งŒ, ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋™์•ˆ switch-over ์ง€์—ฐ์ด ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ ES6 module์„ ๋ฐฐ์šฐ๋ฉด ๋ฏธ๋ž˜์— Javascript ๊ฐœ๋ฐœ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. (Learn ES6 modules today to benefit your Javascript development tomorrow.>์˜์—ญ)

โš ๏ธ **GitHub.com Fallback** โš ๏ธ