2024-06-27.md

🏑

DIL: μ΄νŽ™ν‹°λΈŒ νƒ€μž…μŠ€ν¬λ¦½νŠΈ

μŠ€ν„°λ””: μ›”κ°„ CS, https://github.com/monthly-cs/2024-05-effective-typescript
μž‘μ„±μΌ: 2024-06-27
μž‘μ„±μž: dusunax


8μž₯ νƒ€μž…μŠ€ν¬λ¦½νŠΈ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ κ·Όκ±°: νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν–ˆλ‹€λ©΄ 컴파일 μ‹œμ μ—μ„œ 방지할 수 μžˆμ—ˆμ„ 버그
    • κΉƒν—™ μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œμ νŠΈ 버그: 15%
    • 에어비앀비 진행 ν”„λ‘œμ νŠΈ 사후 뢄석 post-mortem 6κ°œμ›”μΉ˜: 38%
  • λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ€? μ μ§„μ μœΌλ‘œ!
    • noImplicitAny off

μ•„μ΄ν…œ 58: λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ μž‘μ„±ν•˜κΈ°

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈ => νŠΉμ • λ²„μ „μ˜ js둜 컴파일 κ°€λŠ₯, 트랜슀파일러 transpiler 둜 μ‚¬μš©ν•  수 μžˆλ‹€.
  • μ˜›λ‚  λ²„μ „μ˜ JSλ₯Ό λͺ¨λ˜ν•˜κ²Œ λ°”κΎΈλŠ” μž‘μ—…λ„ νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ „ν™˜ μž‘μ—…μ˜ 일뢀라고 λ³Ό 수 μžˆλ‹€.
    • μ΅œμ‹  JS κΈ°λŠ₯도 체크되기 λ•Œλ¬Έμ— μ½”λ“œ μž‘μ„± μ‹œμ— 도움도 받을 수 있고 & μ œλŒ€λ‘œλœ μ‚¬μš©λ²•μ„ 읡힐 λ•Œ 도움됨
    • μ£Όμš” κΈ°λŠ₯: ECMAScript Module, ES2015 Class

ECMAScript Module

  • ES2015 μ΄μ „μ—λŠ” μ½”λ“œλ₯Ό κ°œλ³„ λͺ¨λ“ˆλ‘œ λΆ„ν• ν•˜λŠ” 방법이 μ—†μ—ˆλ‹€. μ§€κΈˆμ€?

1. <script type="module">:

<script type="module">
  import { myFunction } from "./myModule.js";
  myFunction();
</script>

HTMLμ—μ„œ <script type="module">을 μ‚¬μš©ν•˜λ©΄ ES6 λͺ¨λ“ˆμ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μœ„ μ˜ˆμ œμ—μ„œλŠ” myModule.jsμ—μ„œ myFunction을 κ°€μ Έμ™€μ„œ ν˜ΈμΆœν•©λ‹ˆλ‹€.

2. μˆ˜λ™ μ—°κ²°:

// file1.js
const part1 = "Hello, ";

// file2.js
const part2 = "World!";

// combined.js
const part1 = "Hello, ";
const part2 = "World!";
console.log(part1 + part2); // "Hello, World!"

μˆ˜λ™ 연결은 μ—¬λŸ¬ 파일의 μ½”λ“œλ₯Ό ν•˜λ‚˜μ˜ 파일둜 μˆ˜λ™μœΌλ‘œ ν•©μΉ˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, file1.js와 file2.js의 λ‚΄μš©μ„ combined.js에 λ³΅μ‚¬ν•˜μ—¬ λΆ™μ—¬λ„£μŠ΅λ‹ˆλ‹€.

3. Makefile:

all: combined.js

combined.js: file1.js file2.js
    cat file1.js file2.js > combined.js

Makefile은 ν”„λ‘œμ νŠΈ λΉŒλ“œ 과정을 μžλ™ν™”ν•˜λŠ” νŒŒμΌμž…λ‹ˆλ‹€. μœ„ μ˜ˆμ œλŠ” file1.js와 file2.jsλ₯Ό combined.js둜 κ²°ν•©ν•˜λŠ” λͺ…령을 ν¬ν•¨ν•©λ‹ˆλ‹€.

4. NodeJS require:

// module1.js
module.exports = function () {
  console.log("Hello from module1");
};

// main.js
const module1 = require("./module1");
module1(); // "Hello from module1"

Node.jsμ—μ„œ requireλ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“ˆμ„ κ°€μ Έμ˜΅λ‹ˆλ‹€. module1.jsμ—μ„œ ν•¨μˆ˜λ₯Ό 내보내고, main.jsμ—μ„œ require둜 κ°€μ Έμ™€μ„œ ν˜ΈμΆœν•©λ‹ˆλ‹€.

5. AMD define 콜백:

// module.js
define(["dependency"], function (dependency) {
  return function () {
    console.log("Hello from AMD module");
  };
});

// main.js
require(["module"], function (module) {
  module(); // "Hello from AMD module"
});

AMD ν˜•μ‹μ—μ„œλŠ” define ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“ˆμ„ μ •μ˜ν•˜κ³ , 쒅속성을 λͺ…μ‹œν•©λ‹ˆλ‹€. require둜 λͺ¨λ“ˆμ„ κ°€μ Έμ™€μ„œ μ‚¬μš©ν•©λ‹ˆλ‹€.

6. νƒ€μž…μŠ€ν¬λ¦½νŠΈ 자체적 λͺ¨λ“ˆ:

// a.ts
module A {
  export function sayHello() {
    console.log("Hello from module A");
  }
}

// b.ts
/// <reference path="a.ts" />
module B {
  export function callA() {
    A.sayHello();
  }
}

// main.ts
/// <reference path="a.ts" />
/// <reference path="b.ts" />
B.callA();

/// <reference path="...">λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€λ₯Έ 파일의 λ‚΄μš©μ„ μ°Έμ‘°ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ TypeScript 컴파일러λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“  νŒŒμΌμ„ ν•˜λ‚˜λ‘œ 병합할 수 μžˆμŠ΅λ‹ˆλ‹€.

ECMAScript Module

  • ES2015 이후 ν‘œμ€€
  • λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ λŒ€μƒ JS μ½”λ“œκ°€ 단일 νŒŒμΌμ΄κ±°λ‚˜ λΉ„ν‘œμ€€ λͺ¨λ“ˆ μ‹œμŠ€ν…œ(μœ„μ— λͺ¨λ“ˆλ“€)을 μ‚¬μš©ν•œλ‹€λ©΄? ESλͺ¨λ“ˆλ‘œ μ „ν™˜ν•˜λŠ” 것이 μ’‹λ‹€.
    • ν”„λ‘œμ νŠΈμ— 따라 μ›ΉνŒ©, ts-nodeκ°€ ν•„μš”ν•œ 경우 있음
  • λͺ¨λ“ˆ λ‹¨μœ„λ‘œ 점진적 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ„ ν•  수 있음!
// CommonJS
// a.js
const b = require("./b");
console.log(b.name);

//b.js
const name = "Module B";
module.exports = { name };

// ECMAScript module
// a.ts
import * as b from "./b";
console.log(b.name);

// b.ts
export const name = "Module B";