ES6 modules, Node.js and the Michael Jackson Solution - Lee-hyuna/33-js-concepts-kr GitHub Wiki

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค๋ฅธ ํŒŒ์ผ๋กœ ๊ธฐ๋Šฅ์„ ๊ฐ€์ ธ์˜ค๊ณ  ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ํ‘œ์ค€ ๋ฐฉ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค.
์Œ, ์žˆ๋‹ค๋ฉด ๊ธ€๋กœ๋ฒŒ๋ณ€์ˆ˜ ์ •๋„? ์˜ˆ๋ฅผ ๋“ค์ž๋ฉด:

<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script><script>
// `$` variable available here
</script>

์ด์ƒ๊ณผ๋Š” ๋จผ ๋ช‡ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ๋‹ค:

  • ๋™์ผํ•œ ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ noConflict() ๋ฐฉ์‹์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
  • cyclic references๋ฅผ ํ•  ์ˆ˜ ์—†๋‹ค. A๋ชจ๋“ˆ์ด B๋ชจ๋“ˆ์— ์˜์กดํ•˜๊ฑฐ๋‚˜ ๊ทธ ๋ฐ˜๋Œ€์ธ ๊ฒฝ์šฐ, ์–ด๋–ป๊ฒŒ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ถ™์ด๋‚˜์š”?
  • <script> ํƒœ๊ทธ๋ฅผ ๋ถ™์ด๋Š” ์ˆœ์„œ๋Š” ์ค‘์š”ํ•˜๊ณ  ์œ ์ง€ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.


CommonJS to the rescue

Node.js์™€ ๋‹ค๋ฅธ ์„œ๋ฒ„์ธก JavaScript ์†”๋ฃจ์…˜์ด ๋‚˜ํƒ€๋‚˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ, ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด CommonJS๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
๊ฐ€์ ธ์˜ค๊ธฐ/๋‚ด๋ณด๋‚ด๊ธฐ ๋ฌธ์ œ์™€ ๊ด€๋ จํ•˜์—ฌ, ์ด ๊ทœ๊ฒฉ์€ ๋Ÿฐํƒ€์ž„์— ์˜ํ•ด ์ฃผ์ž…๋˜๋Š” require() ํ•จ์ˆ˜์™€ ๋‚ด๋ณด๋‚ด๊ธฐ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๋‚ด๋ณด๋‚ด๊ธฐ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•œ๋‹ค.

Note: CommonJS๋งŒ ๊ทœ๊ฒฉ์€ ์•„๋‹ˆ๋‹ค, UMD์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์€ ํ”„๋ŸฐํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ ๋‘˜ ๋‹ค ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

์‹œ๊ฐ„์ด ํ๋ฅผ์ˆ˜๋ก ํŠนํžˆ ํ•œ ํŽ˜์ด์ง€์งœ๋ฆฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๋“ค์ด ํญ๋ฐœ์ ์œผ๋กœ ๋Š˜์–ด๋‚ฌ๋‹ค.
ํ”„๋ก ํŠธ์—”๋“œ์— ๋” ํฐ ์ฝ”๋“œ ๋ฒ ์ด์Šค๊ฐ€ ์žˆ๊ณ  ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ ๊ฐ„์— ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•ด์•ผ ํ•  ํ•„์š”์„ฑ ๋•Œ๋ฌธ์—, ์ข€ ๋” ํŽธํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด ์›นํŒฉ๊ณผ ๊ฐ™์€ ๋งŽ์€ ํˆด์ด CJS ๊ทœ๊ฒฉ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €๊ฐ€ require()๋ฅผ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ exports๋ฅผ ๋‚ด์žฅํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ Œ์Šค์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜๋Š” ์ผ์€ ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.



How ES6 modules work and why Node.js hasnโ€™t implemented it yet

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋งŽ์€ ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚˜๋ฉด์„œ ์ƒ๊ฒผ๋˜ ๋ฌธ์ œ๋“ค์ด ์žˆ๋Š”๋ฐ ES6๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋˜ ๋ถ€๋ถ„๋“ค์„ ์ปดํŒŒ์ผ ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค. ES modules๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒจ๋‚˜๊ฒŒ ๋˜์—ˆ์„๊นŒ

ํ•˜์ง€๋งŒ import๋ฅผ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ๋น„๊ตํ•ด๋ณด์ž๋ฉด:

const { helloWorld } = require('./b.js') // CommonJS
import { helloWorld } from './b.js' // ES modules

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ธฐ๋Šฅ์„ ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•:

// CommonJS
exports.helloWorld = () => {
  console.log('hello world')
}
// ES modules
export function helloWorld () {
  console.log('hello world')
}

์—„์ฒญ ๋น„์Šทํ•˜์ฃ ?

Node.js๊ฐ€ ES6๋ฅผ ๊ตฌํ˜„ํ•œ ์ง€ ์˜ค๋ž˜์ง€๋งŒ, ES6 ๋ชจ๋“ˆ ์ง€์›์„ ์œ„ํ•ด์„œ๋Š” 2017๋…„ ๋ง๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋Ÿฐํƒ€์ž„ ๋’ค์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค!
ES6 ๋ชจ๋“ˆ์ด CJS์™€ ๋น„์Šทํ•˜๋‹ค๋ฉด Node.js์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์™œ ๊ทธ๋ ‡๊ฒŒ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š”๊ฐ€?

์ด ๊ตฌ๋ฌธ์€ ๋‘ ์‹œ์Šคํ…œ ๋ชจ๋‘์—์„œ ๋งค์šฐ ์œ ์‚ฌํ•˜์ง€๋งŒ ์˜๋ฏธ๋Š” ๋งค์šฐ ๋‹ค๋ฅด๋‹ค. 100% ํ˜ธํ™˜๋˜๋„๋ก ํŠน๋ณ„ํ•œ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•œ edge ์ผ€์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ES ๋ชจ๋“ˆ์ด Node.js์—์„œ ๊ตฌํ˜„๋˜์ง€ ์•Š๋”๋ผ๋„ ์ผ๋ถ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌํŒŒ๋ฆฌ 10.1์—์„œ ๊ทธ๊ฒƒ๋“ค์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์˜ˆ๋ฅผ ๋ณด๊ณ  ์™œ ์ค‘์š”ํ•œ์ง€ ์•Œ์•„๋ณด์ž. ๋‚˜๋Š” ์ด ์„ธ ๊ฐœ์˜ ํŒŒ์ผ์„ ๋งŒ๋“ค์—ˆ๋‹ค

// index.html
<script type="module" src="./a.js"></script>
// a.js
console.log('executing a.js')
import { helloWorld } from './b.js'
helloWorld()
// b.js
console.log('executing b.js')
export function helloWorld () {
  console.log('hello world')
}

์ฝ˜์†”์„ ์‹คํ–‰ํ•˜๋ฉด ํ‘œ์‹œ๋˜๋Š” ๋‚ด์šฉ ๊ทธ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

executing b.js
executing a.js
hello world

CJS๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Node.js์—์„œ ์‹คํ–‰ํ•˜๋Š” ๋™์ผํ•œ ์ฝ”๋“œ:

// a.js
console.log('executing a.js')
import { helloWorld } from './b.js'
helloWorld()
// b.js
console.log('executing b.js')
export function helloWorld () {
  console.log('hello world')
}

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์ค„ ๊ฒƒ์ด๋‹ค.

executing a.js
executing b.js
hello world

๊ทธ๋ž˜์„œ,โ€ฆ ๊ทธ๊ฒƒ์€ ๋‹ค๋ฅธ ์ˆœ์„œ๋กœ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ–ˆ๋‹ค. ์ด๋Š” ES6 ๋ชจ๋“ˆ์„ ๋จผ์ € ๊ตฌ๋ฌธ ๋ถ„์„(์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ )ํ•œ ๋‹ค์Œ ๋Ÿฐํƒ€์ž„์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ฐพ์•„ ๋กœ๋“œํ•œ ํ›„ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๊ฒƒ์„ ๋น„๋™๊ธฐ ๋ถ€ํ•˜๋ผ๊ณ  ํ•œ๋‹ค.

๋ฐ˜๋ฉด Node.js๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ ์ข…์†์„ฑ์„ ๋กœ๋“œํ•œ๋‹ค. ๋งŽ์€ ๊ฒฝ์šฐ์— ์ด๊ฒƒ์€ ์•„๋ฌด๋Ÿฐ ์ฐจ์ด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ์ „ํ˜€ ๋‹ค๋ฅธ ํ–‰๋™์ด๋‹ค.

Node.js์™€ ์›น๋ธŒ๋ผ์šฐ์ €๋Š” ์ด์ „ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•˜๋Š” ์ƒˆ๋กœ์šด ๋กœ๋”ฉ ๋ฐฉ์‹์„ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์–ธ์ œ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ทธ๋ฆฌ๊ณ  ์–ธ์ œ ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ? ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์œ ํ˜• ์†์„ฑ๊ณผ ํ•จ๊ป˜ ์˜ˆ์—์„œ ๋ณด์•˜๋“ฏ์ด <script> ์ˆ˜์ค€์—์„œ ์ง€์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ์‚ฌ์‹ค์„ ์•Œ๊ณ  ์žˆ๋‹ค.

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

ํ•˜์ง€๋งŒ Node.js๋Š” ์–ด๋–ป๊ฒŒ ์•Œ๊นŒ? ์ด๊ฒƒ์— ๋Œ€ํ•ด์„œ ๋งŽ์€ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ๊ณ  (๊ตฌ๋ฌธ์„ ๋จผ์ € ํ™•์ธํ•œ ๋‹ค์Œ์— ๋ชจ๋“ˆ๋กœ ์ทจ๊ธ‰ํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋ฉด์„œ) ๊ทœ์ •ํ•˜๋Š” ์ œ์•ˆ๋“ค์ด ๋งŽ์ด ์žˆ์—ˆ๋‹ค(package.json file,...) ๋งˆ์ง€๋ง‰์œผ๋กœ ์Šน์ธ๋œ ์ œ์•ˆ์€ Michael Jackson ์†”๋ฃจ์…˜์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ์ผ์„ ES6 ๋ชจ๋“ˆ๋กœ ๋กœ๋“œํ•˜๋ ค๋ฉด .js ๋Œ€์‹  .mjs๋ผ๋Š” ๋‹ค๋ฅธ ํ™•์žฅ์ž๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

ํ™•์žฅ๋ช…(.mjs)์€ ์ด๋ฅผ Michael Jackson ๋ถ€๋ฅด๋Š” ์ด์œ ๋‹ค.

์ฒ˜์Œ์—๋Š” ์ข‹์ง€์•Š์€ ๊ฒฐ์ •์œผ๋กœ ๋ณด์˜€์ง€๋งŒ ์ง€๊ธˆ์€ ์ตœ์„ ์˜ ํ•ด๊ฒฐ์ฑ…์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ์€ ์‰ฝ๊ณ  ์–ด๋–ค ๋„๊ตฌ(ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ, IDE, ์ „์ฒ˜๋ฆฌ๊ธฐ)๊ฐ€ ํŒŒ์ผ์„ ES6 ๋ชจ๋“ˆ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ์ง€ ๋ง์•„์•ผ ํ• ์ง€ ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์„ ์•Œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

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