Skip to content

Latest commit

Β 

History

History
417 lines (287 loc) Β· 17.4 KB

step9_js_module.md

File metadata and controls

417 lines (287 loc) Β· 17.4 KB

λ¬Έμ„œ λͺ©λ‘μœΌλ‘œ λŒμ•„κ°€κΈ°

STEP 9, 10

πŸ’‘μ§ˆμ˜μ‘λ‹΅μ€ https://github.com/pul8219/TIL Issues νƒ­μ˜ μ•Œλ§žμ€ step μ΄μŠˆμ•ˆμ— λ‚¨κ²¨μ£Όμ„Έμš”. ➑️ Issueνƒ­μœΌλ‘œ 이동

  • μž‘μ„±μž: Wol-dan (@pul8219)
  • μŠ€ν„°λ”” 주제: FrontEnd λ©΄μ ‘ μŠ€ν„°λ”” https://gitlab.com/siots-study/topics/-/wikis/home
  • 곡뢀 λ²”μœ„: λͺ¨λ“ˆ λͺ¨λ“ˆμ˜ 역사와 μ’…λ₯˜ μ€‘μ‹¬μœΌλ‘œ 정리할 것(STEP 9) + λͺ¨λ“ˆ 문법(STEP 10)
  • κΈ°ν•œ: 9/12(ν† ) ~ 9/15(ν™”) (STEP 9), 9/18(ν† ) ~ 9/22(ν™”) (STEP 10)

보좩 ν•„μš”

  • jsμ—μ„œ '와 "
  • λͺ¨λ“ˆ 레벨 μŠ€μ½”ν”„
  • export ν•˜λŠ” λͺ¨λ“ˆμ€ 항상 β€œuse strict” 이닀.
  • λΈŒλΌμš°μ € λͺ¨λ“ˆ λ¬Έμ„œ μ°Έκ³ 
  • export default

λͺ©μ°¨

λͺ¨λ“ˆμ΄λž€?

  • λͺ¨λ“ˆμ΄λž€ λ³„λ„λ‘œ λΆ„λ¦¬λœ μž¬μ‚¬μš© κ°€λŠ₯ν•œ μ½”λ“œ 쑰각을 μ˜λ―Έν•œλ‹€.
  • μ‰½κ²Œ λ§ν•˜λ©΄ 파일 ν•˜λ‚˜λ₯Ό μ˜λ―Έν•œλ‹€. 슀크립트 ν•˜λ‚˜λŠ” λͺ¨λ“ˆ ν•˜λ‚˜μ΄λ‹€.
  • λͺ¨λ“ˆμ€ 세뢀사항을 μΊ‘μŠν™”ν•˜κ³  ν•„μš”ν•œ APIλ§Œμ„ 외뢀에 κ³΅κ°œν•œλ‹€.
  • λͺ¨λ“ˆμ€ κΈ°λŠ₯λ³„λ‘œ λΆ„λ¦¬λ˜κ³  μž¬μ‚¬μš©μ„±μ΄ μ’‹μ•„ 개발 νš¨μœ¨μ„±κ³Ό μœ μ§€λ³΄μˆ˜μ„±μ„ 높인닀.

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λͺ¨λ“ˆ

  • μ›λž˜ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λͺ¨λ“ˆν™”와 거리가 λ¨Ό μ–Έμ–΄μ˜€λ‹€.
  • 그런데 ν”„λ‘ νŠΈμ—”λ“œ ν”„λ‘œμ νŠΈ 규λͺ¨κ°€ 컀지고 μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ„ ν•„μš”μ— 따라 κ°€μ Έμ˜€κ³ , λ³„λ„μ˜ λͺ¨λ“ˆλ‘œ λΆ„ν• ν•˜κΈ° μœ„ν•œ λ©”μ»€λ‹ˆμ¦˜ ν•„μš”μ„±μ΄ μ¦λŒ€. ES6에 λͺ¨λ“ˆ μ‹œμŠ€ν…œμ΄ 좔가됨.
  • λͺ¨λ“ˆ μ‚¬μš©μ„ κ°€λŠ₯μΌ€ν•˜λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 라이브러리, ν”„λ ˆμž„μ›Œν¬μ˜ λ“±μž₯(RequireJS, CommonJS, AMD, μ΅œκ·Όμ—λŠ” Webpack, Babel)

λͺ¨λ“ˆ μŠ€μ½”ν”„

  • λͺ¨λ“ˆ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λ“€μ€ λͺ¨λ“ˆ λ‚΄λΆ€μ˜ κ°€μž₯ λ°”κΉ₯ μŠ€μ½”ν”„μ—μ„œ μ„ μ–Έν–ˆλ”λΌλ„ μ „μ—­ μŠ€μ½”ν”„/μ „μ—­ λ³€μˆ˜μ— μ €μž₯λ˜μ§€ μ•Šκ³  λͺ¨λ“ˆ μŠ€μ½”ν”„ λ‚΄μ—μ„œ μ„ μ–Έλ˜κΈ° λ•Œλ¬Έμ— μ „μ—­ λ³€μˆ˜κ°€ μ˜€μ—Όλ  걱정은 ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.
  • λͺ¨λ“ˆ μŠ€μ½”ν”„μ— μ„ μ–Έλœ 이름은 ν•΄λ‹Ή λͺ¨λ“ˆμ„ export ν•˜μ§€ μ•Šμ„ 경우, ν•΄λ‹Ή λͺ¨λ“ˆ λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ λͺ¨λ“ˆμ˜ 역사와 문법

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 슀크립트 μ½”λ“œλ₯Ό 파일둜 λ‚˜λˆ  <script> νƒœκ·Έλ‘œ λΆˆλŸ¬μ˜€λŠ” 방식이 초기 λͺ¨λ“ˆν™”μ˜ μ „λΆ€μ˜€λ‹€. 이 λ°©μ‹μ˜ λ¬Έμ œμ μ€ λ‹€μŒκ³Ό κ°™λ‹€.

  • μ „μ—­ λ³€μˆ˜ 곡간이 μ˜€μ—Όλ  수 있음
  • λ‹€λ₯Έ μ‚¬λžŒμ˜ μ½”λ“œλ₯Ό μ΄μš©ν•  λ•Œ μ˜μ‘΄μ„± 관계 확인이 어렀움
  • νŒŒμΌλ“€μ„ λ‘œλ“œν•˜λŠ” μˆœμ„œκ°€ μ€‘μš”ν•΄μ§€λ©° 이λ₯Ό ν•΄κ²°ν•΄μ•Ό ν–ˆμŒ

μ΄λŸ¬ν•œ λ¬Έμ œμ λ“€μ„ κ°œμ„ ν•˜κΈ°μœ„ν•΄ λͺ¨λ“ˆ 기반 μ‹œμŠ€ν…œλ“€μ΄ λ“±μž₯ν–ˆλ‹€.

<script>νƒœκ·Έλ‘œ λ„λ°°ν•˜λŠ” κ²ƒμ˜ 문제점

<!DOCTYPE html>
<html>
  <head>
    ...
    <script src="./foo.js"></script>
    <script src="./bar.js"></script>
    ...
  </head>
  <body></body>
</html>
// foo.js

let num = 1;
// bar.js

let num = 2;
  1. λΈŒλΌμš°μ € μŠ€μ½”ν”„ 문제

foo.js, bar.js νŒŒμΌμ„ 슀크립트 νƒœκ·Έλ‘œ 뢈러였고 각각의 νŒŒμΌμ—μ„œ 같은 μ΄λ¦„μ˜ λ³€μˆ˜λ₯Ό μ“΄λ‹€κ³  ν•΄λ³΄μž. μ΄λ ‡κ²Œ μž‘μ„±ν•˜κ²Œ 되면, κ°€μž₯ 뒀에 쓰인 슀크립트 κΈ°μ€€μœΌλ‘œ λ³€μˆ˜μ΄λ¦„μ΄ μ μš©λ˜μ–΄ foo.jsμ—μ„œ μ‚¬μš©ν•œ λ³€μˆ˜ num은 μ”Ήνžˆκ²Œ λœλ‹€.

  1. μ˜μ‘΄μ„± 관리 문제

λͺ¨λ“ˆμ˜ μ˜μ‘΄μ„± μˆœμ„œλ₯Ό μ „λΆ€ κ³ λ €ν•΄ 슀크립트 νƒœκ·Έλ₯Ό μ μ ˆν•œ 곳에 μœ„μΉ˜μ‹œμΌœμ•Ό ν•œλ‹€.

예λ₯Ό λ“€μ–΄ λͺ¨λ“ˆ Aκ°€ λͺ¨λ“ˆ B에 μ˜μ‘΄ν•œλ‹€λ©΄, λͺ¨λ“ˆ Bκ°€ λ‘œλ“œλ˜κ³ λ‚˜μ„œ λͺ¨λ“ˆ Aκ°€ λ‘œλ“œλ˜μ–΄μ•Ό ν•œλ‹€. 그런데 λ§Œμ•½ μˆ˜μ‹­, 수백개의 λͺ¨λ“ˆλ“€μ— λŒ€ν•΄ μ˜μ‘΄μ„± 관리λ₯Ό ν•΄μ•Ό ν•œλ‹€λ©΄ 생산성이 λ–¨μ–΄μ§ˆ 것이닀.

  1. λ‘œλ“œ μ‹œκ°„

슀크립트 νƒœκ·ΈλŠ” μƒˆλ‘œμš΄ HTTP 컀λ„₯μ…˜μ„ ν•„μš”λ‘œ ν•œλ‹€. HTTP/2(2015)κ°€ λ“±μž₯ν•˜κΈ° μ „μ—λŠ” HTTP 컀λ„₯μ…˜μ΄ 병렬이 μ•„λ‹Œ 직렬적으둜 λ‘œλ“œλκΈ° λ•Œλ¬Έμ— script νƒœκ·Έμ— 파일 ν•œκ°œμ”© 총 100개의 script νƒœκ·Έκ°€ μžˆμ—ˆλ‹€λ©΄ 100번의 HTTP 컀λ„₯μ…˜μ΄ ν•„μš”ν–ˆλ‹€. HTTP 컀λ„₯μ…˜μ„ 톡해 μžλ°”μŠ€ν¬λ¦½νŠΈ λͺ¨λ“ˆμ„ λ‹€μš΄λ°›μ„ λ•Œλ§ˆλ‹€ ν΄λΌμ΄μ–ΈνŠΈ μœ μ €μ˜ λΈŒλΌμš°μ €λŠ” ν•˜μ–—κ²Œ 멈좰있게 λœλ‹€. 슀크립트 νƒœκ·Έκ°€ λ§Žλ‹€λ©΄ μœ μ €λŠ” 더 κΈ°λ‹€λ €μ•Ό ν•œλ‹€. (HTTP/2λŠ” λ©€ν‹°ν”Œλ ‰μ‹±μ„ 톡해 λ³‘λ ¬μ μœΌλ‘œ λ‘œλ“œ)

1, 2, 3λ²ˆμ—μ„œ μ œμ‹œλœ λ¬Έμ œμ™€ μ›ΉνŽ˜μ΄μ§€λ₯Ό λ°©λ¬Έν•œ μœ μ €μ˜ λŒ€κΈ° μ‹œκ°„ μ΅œμ†Œν™”λ₯Ό μœ„ν•œ λͺ¨λ“ˆν™” ν‘œμ€€μ„ μœ„ν•΄ CommonJSκ°€ (절반의) 해결책을 μ œμ‹œν–ˆλ‹€.

CommonJS

μžλ°”μŠ€λ¦½νŠΈλ₯Ό λΈŒλΌμš°μ €μ—μ„œ λΏλ§Œμ•„λ‹ˆλΌ μ„œλ²„μ‚¬μ΄λ“œμ—μ„œλ„ μ‚¬μš©ν•˜κΈ° μœ„ν•΄ λ§Œλ“€μ–΄μ§„ λͺ¨λ“ˆν™” ν‘œμ€€

  • μ„œλ²„μ‚¬μ΄λ“œμš©μœΌλ‘œ μ‚¬μš©ν•  λ•Œ μž₯점이 많음
  • 둜컬 λ””μŠ€ν¬μ—μ„œ λͺ¨λ“ˆμ„ λ‘œλ“œν•  λ•Œ 더 λΉ λ₯΄κ³  κ°„κ²°
  • ν˜„μž¬ Node.jsμ—μ„œ 이 방식을 μ‚¬μš©ν•˜κ³  μžˆλ‹€.

λͺ¨λ“ˆν™”μ˜ 3μš”κ±΄μ„ μΆ©μ‘±μ‹œν‚΄:

  • λͺ¨λ“ˆ νŒŒμΌλ§ˆλ‹€ μŠ€μ½”ν”„κ°€ μ„€μ •λ˜λ―€λ‘œ 각 λͺ¨λ“ˆμ„ λΆˆλŸ¬μ˜€λŠ” μƒμœ„ 파일 λ‚΄μ—μ„œ λ³€μˆ˜ 좩돌이 μ—†λ‹€λ©΄ 이 μ‹œμŠ€ν…œμ—μ„œλŠ” λ³€μˆ˜ 좩돌이 μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€.
  • 파일 덩어리λ₯Ό μž„ν¬ν„°ν•˜λŠ” 게 μ•„λ‹ˆλΌ ν•„μš”ν•œ ν•¨μˆ˜λ‚˜ λ³€μˆ˜λ₯Ό κ°€μ Έμ˜¬ 수 있게 λ˜μ—ˆλ‹€.
  • module.exports, requireλ₯Ό 톡해 μ˜μ‘΄λ˜μ–΄μžˆλŠ” 파일, νŒ¨ν‚€μ§€λ“€μ„ 관리할 수 있게 λ˜μ—ˆλ‹€.

문제점:

  • μ„œλ²„μ‚¬μ΄λ“œμ—μ„œλŠ” jsνŒŒμΌλ§ˆλ‹€ 독립적인 μŠ€μ½”ν”„λ₯Ό λ§Œλ“€κΈ° λ•Œλ¬Έμ— μ „μ—­ 곡간과 뢄리가 λ˜μ§€λ§Œ λΈŒλΌμš°μ €μ—μ„œ λ™μž‘ν•  λ•ŒλŠ” νŒŒμΌλ§ˆλ‹€ λ‹¨μΌν•œ μŠ€μ½”ν”„κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— <script> νƒœκ·Έλ‘œ λ‹¨μˆœνžˆ js νŒŒμΌμ„ λ‘œλ“œν•˜λ©΄ μ—¬μ „νžˆ μ „μ—­λ³€μˆ˜κ°€ μ˜€μ—Όλœλ‹€
  • λΈŒλΌμš°μ €μ—μ„œ λ„€νŠΈμ›Œν¬λ₯Ό 톡해 ν•„μš”ν•œ λͺ¨λ“ˆμ„ 내렀받을 λ™μ•ˆ λΈŒλΌμš°μ €κ°€ 아무일도 ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 문제점이 μžˆλ‹€. (μ‚¬μš©μž κ²½ν—˜ λ‚˜μ˜κ²Œ λ§Œλ“€ 수 있음)
  • CommonJSλŠ” blocking 방식이라 λΈŒλΌμš°μ €μ—μ„œ ν™œμš©ν•  μ‹œ λ„ˆλ¬΄ λŠλ¦¬λ‹€λŠ” 단점이 μžˆλ‹€.
// main.js

const foo = require('foo.js');
const bar = require('bar.js');

require ν•¨μˆ˜κ°€ blocking ν•¨μˆ˜μ΄κΈ° λ•Œλ¬Έμ— μœ„ μ½”λ“œμ—μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈ μΈν„°ν”„λ¦¬ν„°λŠ” require('foo.js')λΌμΈμ—μ„œ μž μ‹œ > λ©ˆμΆ”μ—ˆλ‹€κ°€ μ»¨ν…μŠ€νŠΈλ₯Ό λ°”κΏ” require() μ•ˆμ˜ 과정을 λͺ¨λ‘ 끝내고 κ·Έ 리턴값을 foo에 λ°›κ³  λ‚˜μ„œμ•Ό κ·Έ λ‹€μŒ μ½”λ“œλΌμΈμ„ μ½λŠ”λ‹€.

μ›Ή λΈŒλΌμš°μ €μ—μ„œλŠ” μ„œλ²„μ— requestλ₯Ό λ‚ λ € νŒŒμΌλ“€μ„ μ½μ–΄μ˜€κ²Œ λ˜λŠ”λ° μ΄λ•Œ 속도 μΈ‘λ©΄μ—μ„œ λ¬Έμ œκ°€ μžˆλ‹€. foo.jsλ₯Ό requireν•  > λ•Œ HTTP request ν•œ 번, bar.jsλ₯Ό requireν•  λ•Œ HTTP request ν•œ 번 ν•˜κ²Œ λ˜μ–΄ 톡신 λΉ„μš©μ΄ 많이 λ°œμƒν•œλ‹€. 이것이 > μ„œλ²„μ‚¬μ΄λ“œ 방식을 μ›Ή ν™˜κ²½μ— μ μš©ν•˜κΈ° μ–΄λ €μš΄ μ΄μœ λ‹€.

λ‹€ν–‰νžˆ 2008년에 V8 크둬 엔진이 λ„μž…λ˜μ–΄ event loopλ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ, asyncν•˜κ²Œ λŒμ•„κ°ˆ 수 μžˆλŠ” ν™˜κ²½μ΄ λ§Œλ“€μ–΄μ‘Œλ‹€. async ν•˜λ‹€λŠ” 것은 non-blockingμ΄λΌμ„œ 싀행될 λ•ŒκΉŒμ§€ 기닀리지 μ•Šκ³  ν•¨μˆ˜λ₯Ό 큐에 λ‹΄μ•„ μ—¬λŸ¬ 개의 μž‘μ—…λ“€μ„ λ™μ‹œμ μœΌλ‘œ μˆ˜ν–‰ν•œλ‹€λŠ” 것이닀.

CommonJS 문법

  • λͺ¨λ“ˆν™” 방법: module.exports
  • λͺ¨λ“ˆ λΆˆλŸ¬μ˜€λŠ”(이용) 방법: require
// foo.js

module.exports.foo = function () {
  // ...
};
// bar.js

var foo = require('./foo.js').foo;

export vs module.exports

μ˜ˆμ •

AMD

Asynchronous Module Definition

비동기 μƒν™©μ—μ„œλ„ μžλ°”μŠ€ν¬λ¦½νŠΈ λͺ¨λ“ˆμ„ μ“°κΈ° μœ„ν•΄ CommonJSμ—μ„œ λ…Όμ˜ν•˜λ‹€ ν•©μ˜μ μ„ 찾지 λͺ»ν•˜κ³  λ”°λ‘œ λ…λ¦½ν•œ 그룹이닀. λΈŒλΌμš°μ €μ˜ non-blocking, async μ„±μ§ˆμ„ 적극 ν™œμš©ν•΄ 웹에 μ ν•©ν•œ λͺ¨λ“ˆν™” μ‹œμŠ€ν…œμ„ λ§Œλ“œλ €λŠ” λͺ©ν‘œλ₯Ό 가지고 μžˆμ—ˆλ‹€.

  • AMDλ₯Ό κ΅¬ν˜„ν•œ λŒ€ν‘œμ μΈ λͺ¨λ“ˆμ‹œμŠ€ν…œμ€ Require.js
  • μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ›Ή λΈŒλΌμš°μ €μ—μ„œ μ“°λŠ” 것에 쀑점을 λ‘”λ‹€.
  • λΈŒλΌμš°μ €μ—μ„œ λ„€νŠΈμ›Œν¬λ₯Ό 톡해 λͺ¨λ“ˆμ„ λ‚΄λ € λ°›λŠ” λ•Œ μž₯점이 λ§Žλ‹€. λΈŒλΌμš°μ €μ—μ„œ 비동기 λͺ¨λ“ˆ λ‘œλ”©λ°©μ‹μœΌλ‘œ κ΅¬ν˜„μ„ ν•΄λ†“μ•˜κΈ° λ•Œλ¬Έ.
  • define ν•¨μˆ˜(AMD 만의 νŠΉμ§•)λ₯Ό μ‚¬μš©ν•˜μ—¬ μŠ€μ½”ν”„λ₯Ό λΆ„λ¦¬ν•œλ‹€. 이 ν•¨μˆ˜λŠ” λͺ¨λ“ˆ 배열을 인자둜 가지고 λ‘œλ“œλœ λͺ¨λ“ˆμ„ μ½œλ°±ν•¨μˆ˜μ— μ „λ‹¬ν•œλ‹€.
  • define ν•¨μˆ˜μ˜ 리턴값이 곧 exports 속성이 λœλ‹€.
  • CommonJS와 같이 exports 객체둜 λͺ¨λ“ˆμ„ μ •μ˜ν•˜κ³  λͺ¨λ“ˆμ„ μ‚¬μš©ν•  λ•ŒλŠ” requireν•¨μˆ˜ μ‚¬μš©ν•œλ‹€. require ν•¨μˆ˜λŠ” 의쑴 관계λ₯Ό νŒλ‹¨ν•΄ 쒅속성이 μžˆλŠ” 것을 λ¨Όμ € λ‘œλ“œν•˜κΈ° λ•Œλ¬Έμ— μ˜μ‘΄μ„± λ¬Έμ œλ„ 일정 λΆ€λΆ„ ν•΄κ²°ν•  수 μžˆλ‹€.

문제점:

  • μ„œλ²„μ‚¬μ΄λ“œμ—μ„œ μ‚¬μš©ν•˜λ €κ³  λ§Œλ“  ν•¨μˆ˜λ₯Ό λΈŒλΌμš°μ €μ—μ„œ μ“°λ €λ©΄ AMD ν˜•μ‹μ— 맞좰 λ‹€ λ°”κΏ”μ£Όμ–΄μ•Ό ν•˜λŠ” λ²ˆκ±°λ‘œμ›€μ΄ μžˆλ‹€.
  • AMDκ°€ μ œμ•ˆλœμ§€ μ–Όλ§ˆ λ˜μ§€ μ•Šμ•„ npm(Node Package Manager)이 λ“±μž₯ν•˜κ³  λ§Žμ€ κ°œλ°œμžλ“€μ΄ node.js에 (λŒ€λΆ€λΆ„) CommonJS ν˜•μ‹μœΌλ‘œ λ§Œλ“€μ–΄μ§„ 멋진? λͺ¨λ“ˆλ“€μ„ μ—…λ‘œλ“œν•˜κΈ° μ‹œμž‘ν•˜λ©΄μ„œ CommonJS ν˜•μ‹μœΌλ‘œ λ§Œλ“  μ½”λ“œλ₯Ό AMD μŠ€νƒ€μΌλ‘œ λ³€ν™˜ν•΄μ•Όν•  상황듀이 λ§Žμ•„μ‘Œλ‹€. (μ„œλ²„μ‚¬μ΄λ“œμ˜ μ½”λ“œ λ”°λ‘œ, AMD ν˜•μ‹ μ½”λ“œ λ”°λ‘œ μ΄λ ‡κ²Œ μ§œλŠ” 과정을 ν•˜λ‚˜λ‘œ 쀄이고 이런 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ λͺ¨λ“ˆ λ²ˆλ“€λŸ¬κ°€ λ“±μž₯ν–ˆλ‹€.)

AMD 문법

μ˜ˆμ •

ECMAScript 6μ—μ„œ μΆ”κ°€λœ λͺ¨λ“ˆν™” 기법

  • ES6λΆ€ν„° μžλ°”μŠ€ν¬λ¦½νŠΈ λͺ¨λ“ˆν™”λ₯Ό μ§€μ›ν•œλ‹€. (import/exportλ₯Ό μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆν™”μ˜ ν‘œμ€€)
  • ν˜„μž¬ ES6 λͺ¨λ“ˆμ„ μ§€μ›ν•˜μ§€ μ•ŠλŠ” λΈŒλΌμš°μ €λ“€λ„ μžˆμ–΄ SystemJS, RequireJS λ“±μ˜ λͺ¨λ“ˆ λ‘œλ” λ˜λŠ” Webpack λ“±μ˜ λͺ¨λ“ˆ λ²ˆλ“€λŸ¬λ₯Ό 많이 μ‚¬μš©ν•œλ‹€.
  • ECMA(European Computer Manufacturer's Association) International μ—μ„œ μ •ν•œ μžλ°”μŠ€ν¬λ¦½νŠΈ ν‘œμ€€μ΄ ECMAScript이닀.
  • ES6(ECMAScript 6)은 ECMA 2015라고도 λΆˆλ¦°λ‹€.

ES6μ—μ„œ ν‘œμ€€ν™”λœ λͺ¨λ“ˆ κ°€μ Έμ˜€κΈ°λŠ” λ‹€μŒκ³Ό κ°™λ‹€. main.jsμ—μ„œ foo.js νŒŒμΌμ— μžˆλŠ” foo ν•¨μˆ˜λ₯Ό κ°€μ Έμ˜€λŠ” μ½”λ“œμ΄λ‹€.

// main.js

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

export default { foo };

λͺ¨λ“ˆν™”μ˜ 기본적인 μš”κ±΄λ“€

  • λ…λ¦½λœ μŠ€μ½”ν”„κ°€ μ‘΄μž¬ν•΄μ•Ό ν•œλ‹€.(μ „μ—­ λ³€μˆ˜ μ˜μ—­μ„ λ”λŸ½νžˆμ§€ μ•Šλ„λ‘!)
  • 파일 λ©μ–΄λ¦¬λ‚˜ ν•˜λ‚˜ μ „λΆ€λ₯Ό λͺ¨λ“ˆλ‘œ κ°€μ Έμ˜€λŠ” 것이 μ•„λ‹ˆλΌ(ex.<script> νƒœκ·Έλ‘œ λͺ¨λ“ˆμ„ κ°€μ Έμ˜€λŠ” 경우) νŒŒμΌμ—μ„œ ν•¨μˆ˜λ‚˜ 객체λ₯Ό κ°€μ Έμ˜¬ 수 μžˆμ–΄μ•Ό ν•œλ‹€.(가독성을 λ†’μž„)
  • μ˜μ‘΄μ„± 관리가 μˆ˜μ›”ν•΄μ•Ό ν•œλ‹€.(κ·Έλž˜μ•Ό ν™•μž₯이 쉽닀)

ESM(ECMAScript Module)

ES6λΆ€ν„° μ§€μ›ν•˜λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 자체 λ‚΄μž₯ λͺ¨λ“ˆ μ‹œμŠ€ν…œ

λ‹€μŒ 예제 μ½”λ“œλ“€μ„ 보자.

μ•„λž˜ μ½”λ“œλŠ” HTML νŒŒμΌμ—μ„œ λͺ¨λ“ˆμ„ κ°€μ Έμ˜€λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•œ 것이닀.

<!-- πŸ“ index.html -->
<!-- HTML νŒŒμΌμ—μ„œ λͺ¨λ“ˆ κ°€μ Έμ˜€κΈ° -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Module test</title>
    <!-- 404 μ—λŸ¬ λ•Œλ¬Έμ— λ„£μ–΄μ€€ μ½”λ“œ -->
    <link rel="shortcut icon" href="#" />
    <script type="module" src="lib.mjs"></script>
    <script type="module" src="app.mjs"></script>
  </head>
  <body></body>
</html>

ES6 λͺ¨λ“ˆ 파일의 ν™•μž₯μžλŠ” λͺ¨λ“ˆμΈ 것을 λΆ„λͺ…νžˆ ν•˜κΈ° μœ„ν•΄ .mjs ν™•μž₯자λ₯Ό μ‚¬μš©ν•œλ‹€.

export

λͺ¨λ“ˆ μŠ€μ½”ν”„μ—μ„œ λͺ¨λ“ˆ λ°–μœΌλ‘œ 이름듀을 내보낼 λ•ŒλŠ” export ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

// πŸ“ module.mjs

export const birthday = '🍰';

export function collabo(a, b) {
  return `${a} + ${b}`;
}

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

// + λͺ¨λ“ˆλ°–μœΌλ‘œ 내보낼 λ•Œ ν•œλ²ˆμ— 내보내고 μ‹Άλ‹€λ©΄ μœ„ μ½”λ“œμ—μ„œ export ν‚€μ›Œλ“œλ₯Ό μ œκ±°ν•œ λ‹€μŒ, μΆ”κ°€λ‘œ λ‹€μŒκ³Ό 같이 써쀀닀.
export { birthday, collabo, Person };

import

λͺ¨λ“ˆμ„ κ°€μ Έμ˜¬ λ•ŒλŠ” import ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

// πŸ“ app.mjs

// 경우 1
import { birthday, collabo, Person } from './lib.mjs';

console.log(birthday); // 🍰
console.log(collabo('πŸ₯š', 'πŸ₯—')); // πŸ₯š + πŸ₯—
console.log(new Person('yurim')); // Person { name: "yurim" }

// 경우 2
// μœ„ μ½”λ“œλ₯Ό μ•„λž˜ μ½”λ“œμ²˜λŸΌ μž‘μ„±ν•˜μ—¬ ν•œλ²ˆμ— λͺ¨λ“ˆμ„ κ°€μ Έμ˜¬ μˆ˜λ„ 있음

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

console.log(lib.birthday);
console.log(lib.collabo('πŸ₯š', 'πŸ₯—'));
console.log(new lib.Person('yurim'));

// 경우 3
// λͺ¨λ“ˆμ„ κ°€μ Έμ˜€λ©° 이름 변경도 κ°€λŠ₯

import { birthday as bd, collabo as mix, Person as P } from './lib.mjs';

console.log(bd);
console.log(mix('πŸ₯š', 'πŸ₯—'));
console.log(new P('yurim'));

index.html 파일 μ‹€ν–‰ κ²°κ³Ό

image

export default

ν•˜λ‚˜μ˜ λ°μ΄ν„°λ§Œ export ν•  경우 default ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

default ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  경우, var, let, const μ‚¬μš©μ΄ λΆˆκ°€ν•˜λ‹€.

default둜 export된 λͺ¨λ“ˆμ€ importμ‹œ {} 없이 μž„μ˜ μ΄λ¦„μœΌλ‘œ κ°€μ Έλ‹€ μ“΄λ‹€.

// ν•˜λ‚˜μ˜ λ°μ΄ν„°λ§Œ exportν•  경우 default μ‚¬μš©

export default functon(x){
  return x + x;
}
// default ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œ λͺ¨λ“ˆμ„ κ°€μ Έμ˜€λŠ” 예

import double from './lib.mjs';

console.log(double(2)); // 4

References

Q&A

νŒ€μ›λ“€ κ²°κ³Όλ¬Ό 및 μ§ˆμ˜μ‘λ‹΅&μ½”λ“œλ¦¬λ·°

유림

step 9, 10 https://github.com/pul8219/TIL/blob/master/Documents/FrontEnd-Study/step9_js_module.md

μ€μ˜

step9

step10

λ™μΌν•œ λͺ¨λ“ˆμ΄ μ—¬λŸ¬ κ³³μ—μ„œ μ‚¬μš©λ˜λ”λΌλ„ λͺ¨λ“ˆμ€ 졜초 호좜 μ‹œ 단 ν•œλ²ˆλ§Œ μ‹€ν–‰λœλ‹€.

type="module" 의 νŠΉμ§• > 지연싀행

import.meta μ„€λͺ… λΆ€λΆ„μ˜ μ½”λ“œλ‚΄μ— 보면 import.meta.url을 μ“Έμ‹œμ— 인라인 μŠ€ν¬λ¦½νŠΈκ°€ μœ„μΉ˜ν•΄ μžˆλŠ” html νŽ˜μ΄μ§€μ˜ URL 이라 μž‘μ„±λ˜μ–΄ μžˆλŠ”λ° ν˜Ήμ‹œ 인라인 μŠ€ν¬λ¦½νŠΈκ°€ λ¬΄μ—‡μΈκ°€μš”?.. κ²°κ΅­ 이 alert λ¬Έμ—μ„œ 좜λ ₯λ˜λŠ” κ²°κ³Όκ°€ 무엇인지 잘 λͺ¨λ₯΄κ² μ–΄μ„œ μ§ˆλ¬Έλ“œλ¦½λ‹ˆλ‹€.

노원

step9 https://github.com/quavious/hell_script/blob/master/chapter10.js

step10 https://github.com/quavious/hell_script/blob/master/chapter9.js

잘 μ½μ—ˆμŠ΅λ‹ˆλ‹€. μœ μ €μ˜ νŠΉμ •ν•œ λ™μž‘μ— λͺ¨λ“ˆμ΄ μž‘λ™λ˜λ„λ‘ ν•˜μ—¬ λͺ¨λ“ˆ λ‘œλ“œ μ‹œκ°„μ„ μ€„μ΄λŠ” 뢀뢄은 μ •λ¦¬ν•˜μ§€ λͺ»ν–ˆλŠ”데 도움이 λμŠ΅λ‹ˆλ‹€.!!

λͺ¨λ“ˆμ€ 기본적으둜 엄격λͺ¨λ“œμ΄λ‹€.

const module... 및 import module... 와 같은 정적 import 문은 λͺ¨λ“  λͺ¨λ“ˆμ„ 뢈러였고 λ‚˜μ„œ μ½”λ“œκ°€ μ‹€ν–‰λœλ‹€. λ°˜λŒ€λ‘œ μœ μ €μ˜ νŠΉμ •ν•œ λ™μž‘μ— λͺ¨λ“ˆμ΄ μž‘λ™λ˜λ„λ‘ ν•  수 μžˆλ‹€. 전체 λͺ¨λ“ˆ λ‘œλ“œ μ‹œκ°„μ„ 쀄일 수 μžˆλ‹€.

//<script type="module">
(async () => {
  const foo = './lib.mjs';
  const { func1, func2 } = await import(foo);
  await func2();
  func1();
  const { func3 } = require('./onemodule.js');
  await func3();
  console.log('Module loaded dynamically');
})();
//</script>
ν˜„μž¬ μ›Ή λΈŒλΌμš°μ €λŠ” ES6 λͺ¨λ“ˆμ„ μ§€μ›ν•˜κ³  μžˆμ§€ μ•Šλ‹€.
script νƒœκ·Έμ— type="text/module"을 λͺ…μ„Έν•˜κ±°λ‚˜
Webpack, Browserify λ“±μ˜ 라이브러리λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.


예)
React도 create-react-app으둜 μ‹€ν–‰ν•΄μ„œ λ¦¬μ•‘νŠΈ ν”„λ‘œμ νŠΈλ₯Ό 생성 ν›„ μ—΄μ–΄λ³΄μ•˜μ„ λ•Œ
Webpack λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ„€μΉ˜λ˜μ–΄ μžˆλŠ” 것을 확인할 수 μžˆλ‹€.

μ •μ›…

step9 https://www.notion.so/ac4b905296634db0a7caf5ef6a0e94f0?v=c1872030fdb24eb4b08b5a428b8d3284&p=8a5fac2802f74b4cb0063455f2e3830b

step10

ν˜•μš±

step9 https://github.com/khw970421/js-interview/blob/master/const/project9.md

step10 https://github.com/khw970421/js-interview/blob/master/const/project10.md

잘 μ½μ—ˆμŠ΅λ‹ˆλ‹€! export default 문법 μ„€λͺ…λΆ€λ₯Ό λ³΄λ‹ˆ μ œκ°€ 썼던 애맀λͺ¨ν˜Έν•œ μ„€λͺ…μ˜ μˆ˜μ •μ— 도움이 될 것 κ°™μŠ΅λ‹ˆλ‹€. κ°μ‚¬ν•©λ‹ˆλ‹€.