λͺ¨λ˜ JS Deep dive #48 | λͺ¨λ“ˆ

πŸ“Œ λͺ¨λ“ˆ

λͺ¨λ“ˆμ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬μ„±ν•˜λŠ” κ°œλ³„μ  μš”μ†Œλ‘œμ„œ μž¬μ‚¬μš© κ°€λŠ₯ν•œ μ½”λ“œ 쑰각을 λ§ν•œλ‹€. λͺ¨λ“ˆμ΄ μ„±λ¦½ν•˜λ €λ©΄ λͺ¨λ“ˆμ€ μžμ‹ λ§Œμ˜ 파일 μŠ€μ½”ν”„λ₯Ό κ°€μ§ˆ 수 μžˆμ–΄μ•Ό ν•œλ‹€.

즉, λͺ¨λ“ˆμ€ κ°œλ³„μ  μ‘΄μž¬λ‘œμ„œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό λΆ„λ¦¬λ˜μ–΄ μ‘΄μž¬ν•˜λ©°, κ³΅κ°œκ°€ ν•„μš”ν•œ μžμ‚°μ— ν•œμ •ν•˜μ—¬ λͺ…μ‹œμ μœΌλ‘œ 선택적 κ³΅κ°œκ°€ κ°€λŠ₯ν•˜λ‹€. 이λ₯Ό export라 ν•œλ‹€.

export된 λͺ¨λ“ˆμ˜ μžμ‚°μ€ λ‹€λ₯Έ λͺ¨λ“ˆμ—μ„œ μž¬μ‚¬μš©ν•  수 있고, λͺ¨λ“ˆ μ‚¬μš©μžλŠ” λͺ¨λ“ˆμ΄ exportν•œ μžμ‚° 쀑 일뢀 λ˜λŠ” 전체λ₯Ό 선택해 μžμ‹ μ˜ μŠ€μ½”ν”„ λ‚΄λ‘œ λΆˆλŸ¬λ“€μ—¬ μž¬μ‚¬μš©ν•  수 μžˆλ‹€. 이λ₯Ό import라 ν•œλ‹€.


πŸ“Œ JS와 λͺ¨λ“ˆ

JSλŠ” νƒœμƒμ μœΌλ‘œ λͺ¨λ“ˆ μ‹œμŠ€ν…œμ„ μ§€μ›ν•˜μ§€ μ•Šμ•˜λ‹€. λ‹€μ‹œ 말해, 파일 μŠ€μ½”ν”„, import, exportλ₯Ό μ§€μ›ν•˜μ§€ μ•Šμ•˜λ‹€. script νƒœκ·Έλ‘œ λ‘œλ“œν•΄λ„ λΆ„λ¦¬λœ μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌλ“€μ€ κ²°κ΅­ ν•˜λ‚˜μ˜ 파일 내에 μžˆλŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€. 이런 μƒν™©μ—μ„œ μ œμ•ˆλœ 것이 CommonJS와 AMDκ³ , JS λŸ°νƒ€μž„ ν™˜κ²½μΈ Node JSλŠ” λͺ¨λ“ˆ μ‹œμŠ€ν…œμ˜ 사싀상 ν‘œμ€€μΈ CommonJSλ₯Ό μ±„νƒν–ˆλ‹€.


πŸ“Œ ES6λͺ¨λ“ˆ(ESM)

μ΄λŸ¬ν•œ μƒν™©μ—μ„œ ES6μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ JSμ—μ„œλ„ λ™μž‘ν•˜λŠ” λͺ¨λ“ˆ κΈ°λŠ₯을 μΆ”κ°€ν–ˆλ‹€. ESM의 μ‚¬μš©λ²•μ€ script νƒœκ·Έμ— type="module" μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό μΆ”κ°€ν•˜λ©΄ λ‘œλ“œλœ μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ€ λͺ¨λ“ˆλ‘œμ„œ λ™μž‘ν•œλ‹€. ESMμž„μ„ λͺ…ν™•ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄ mjsλ₯Ό μ‚¬μš©ν•  것을 ꢌμž₯ν•œλ‹€.


πŸ“Œ import/export & require/exports

require / exports λŠ” NodeJSμ—μ„œ μ‚¬μš©λ˜κ³  μžˆλŠ” CommonJS ν‚€μ›Œλ“œμ΄κ³  Ruby μ–Έμ–΄ μŠ€νƒ€μΌκ³Ό λΉ„μŠ·ν•˜λ‹€κ³  λ³Ό 수 μžˆλ‹€.

import / export λŠ” ESM λ°©μ‹μœΌλ‘œ Javaλ‚˜ Python μ–Έμ–΄ 방식과 λΉ„μŠ·ν•˜λ‹€.

/* CommonJS  */
const name = require("./module.js");
/* ES6 */
import name from "./module.js";

μœ„ 처럼 import 와 require λŠ” ν™•μ—°νžˆ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— λ‘˜μ„ κ΅¬λΆ„ν•˜λŠ”λ° μžˆμ–΄ 무리가 μ—†λ‹€.

ν•˜μ§€λ§Œ, export 와 exports λŠ” λ‹¨μˆ˜λƒ λ³΅μˆ˜λƒμ˜ 차이 λ•Œλ¬Έμ— λ§Žμ€ 초보 κ°œλ°œμžλ“€μ΄ ν˜Όλ™ν•΄ ν•œλ‹€.

/* CommonJS  */
const name = "고양이";
module.exports = name;
/* ES6 */
const name = "고양이";
export default name;

CommonJS와 ES6λΌλŠ” λͺ¨λ“ˆ μ‹œμŠ€ν…œμ—μ„œλŠ” exports κ°μ²΄λΌλŠ” κ°œλ…μ΄ μ‘΄μž¬ν•˜λŠ”λ°, exportsλŠ” λͺ¨λ“ˆλ‘œλΆ€ν„° λ‚΄λ³΄λ‚΄μ§€λŠ” 데이터듀을 λ‹΄κ³  μžˆλŠ” ν•˜λ‚˜μ˜ 객체이닀.

ES6의 export default ꡬ문이, CommonJS의 module.exports ꡬ문 λ™μž‘μ„ λŒ€μ²΄ν•˜κΈ° μœ„ν•œ 문법이고, exportꡬ문은 exports.λ³€μˆ˜ λ₯Ό λŒ€μ²΄ν•˜κΈ° μœ„ν•œ 문법이라 보면 λœλ‹€.

[Node.js μ—μ„œ import ν‚€μ›Œλ“œ μ‚¬μš© 방법]

비둝 μ •μ‹μ μœΌλ‘œ λ…Έλ“œμ˜ CommonJSλ₯Ό λŒ€μ²΄ν• μˆ˜λŠ” μ—†μ§€λ§Œ, μžλ°”μŠ€ν¬λ¦½νŠΈ λ…Έλ“œ ν”„λ‘œμ νŠΈμ—μ„œ import ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ„λ‘ μ§€μ • 섀정을 ν•  수 μžˆλŠ” 방법 λ˜ν•œ μ‘΄μž¬ν•œλ‹€.

κ³Όκ±°μ—λŠ” import, exportλ₯Ό μΈμ‹μ‹œν‚€κΈ° μœ„ν•΄ λ”°λ‘œ .mjsλΌλŠ” ν™•μž₯자λ₯Ό μ‚¬μš©ν•΄ λͺ¨λ“ˆ ν‚€μ›Œλ“œλ₯Ό κ΅¬λΆ„ν•˜λŠ” 방법을 μ‚¬μš©ν–ˆμ—ˆλ‹€.

예λ₯Όλ“€μ–΄ app.js λŒ€μ‹ μ— app.mjs 둜 μ†ŒμŠ€ νŒŒμΌμ„ λ§Œλ“œλŠ” μ‹μœΌλ‘œ 말이닀.

ν•˜μ§€λ§Œ μ΄μ œλŠ” package.json을 ν†΅ν•΄μ„œ κ°„νŽΈν•˜κ²Œ μ„€μ •ν•  수 μžˆμ–΄μ„œ ν™•μž₯자λ₯Ό λ°”κΎΈμ§€ μ•Šμ•„λ„ import, exportλ₯Ό μ“Έ 수 있게 λ˜μ—ˆλ‹€.

πŸ”— 참고자료

[NODE] πŸ“š require vs import 문법 비ꡐ (CommonJS vs ES6)