2024-06-22.md

๐Ÿก

DIL: ์ดํŽ™ํ‹ฐ๋ธŒ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ

์Šคํ„ฐ๋””: ์›”๊ฐ„ CS, https://github.com/monthly-cs/2024-05-effective-typescript
์ž‘์„ฑ์ผ: 2024-06-22
์ž‘์„ฑ์ž: dusunax


์•„์ดํ…œ 56: ์ •๋ณด๋ฅผ ๊ฐ์ถ”๋Š” ๋ชฉ์ ์œผ๋กœ private ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ

  • ECMAScript 2022 ์ด์ „, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํด๋ž˜์Šค์— ๋น„๊ณต๊ฐœ ์†์„ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์—†์—ˆ๋‹ค
    • ์–ธ๋”์Šค์ฝ”์–ด ์ ‘๋‘์‚ฌ๋ฅผ ๊ด€๋ก€๋กœ ์‚ฌ์šฉํ–ˆ์„ ๋ฟ~~
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ public, protected, private ์ ‘๊ทผ ์ œ์–ด์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณต๊ฐœ ๊ทœ์น™์„ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ์˜คํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค~!
    • ํ•˜์ง€๋งŒ ์ ‘๊ทผ ์ œ์–ด์ž๋Š”? ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํ‚ค์›Œ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ ํ›„์—๋Š” ์ œ๊ฑฐ๋œ๋‹ค.
// TS
class Diary {
  private secret = "cheated on my English test";
}

const diary = new Diary();
diary.secret;
// ~~~ 'secret' ์†์„ฑ์€ private์ด๋ฉฐ 'Diary' ํด๋ž˜์Šค ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// JS ์ปดํŒŒ์ผ ํ›„
class Diary {
  constructor() {
    this.secret = "cheated on my English test"; // private ํ‚ค์›Œ๋“œ๋Š” ์‚ฌ๋ผ์ง, secret์€ ์ผ๋ฐ˜์ ์ธ ์†์„ฑ
  }
}
const diary = new Diary();
diary.secret;

// TS์˜ ์ ‘๊ทผ ์ œ์–ด์ž๋“ค์€? ์ปดํŒŒ์ผ ์‹œ์ ์—๋งŒ ์˜ค๋ฅ˜ ํ‘œ์‹œ. ์–ธ๋”์Šค์ฝ”์–ด๋‚˜ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋Ÿฐํƒ€์ž„์— ํšจ๋ ฅ์ด ์—†๋‹ค.
// ๋‹จ์–ธ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด? TS์—์„œ๋„ private์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
(diary as any).secret; // ์ •์ƒ

์˜ˆ์ œA:

  • JS์—์„œ ์บก์Šํ™”์— ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•
declare function hash(text: string): number;

// ํด๋กœ์ €๋ฅผ ๋งŒ๋“œ๋Š” ์ƒ์„ฑ์ž ์˜ˆ์‹œ
class PasswordChecker {
  checkPassword: (password: string) => boolean;

  constructor(passwordHash: number) {
    // checkPassword ํ•จ์ˆ˜๊ฐ€ ํด๋กœ์ €๋ฅผ ์ด์šฉํ•˜์—ฌ passwordHash ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ
    this.checkPassword = (password: string) => {
      // ์ „๋‹ฌ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•ด์‹œํ™”ํ•˜์—ฌ ์ €์žฅ๋œ ํ•ด์‹œ๊ฐ’๊ณผ ๋น„๊ต
      return hash(password) === passwordHash;
    };
  }
}

const checker = new PasswordChecker(hash("s3cret"));
checker.checkPassword("s3cret"); // true

Closure ์˜ˆ์ œA: ์‹คํ–‰ ๊ณผ์ •

1. ํ•ด์‹œ ํ•จ์ˆ˜ ํ˜ธ์ถœ

  • hash("s3cret")๊ฐ€ 123456์ด๋ผ๋Š” ํ•ด์‹œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •

2. PasswordChecker ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

  • new PasswordChecker(123456) ํ˜ธ์ถœ๋กœ PasswordChecker ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.
  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  passwordHash ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” 123456์ด๋ผ๋Š” ๊ฐ’์„ ๋ฐ›๋Š”๋‹ค.

3. ํด๋กœ์ € ์ƒ์„ฑ

  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ this.checkPassword์— ํ• ๋‹น๋œ ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ
    • passwordHash ๋ณ€์ˆ˜๋ฅผ ์บก์ฒ˜ํ•˜์—ฌ ํด๋กœ์ €๋ฅผ ๋งŒ๋“ฆ => passwordHash์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค
      • this.checkPassword ํ•จ์ˆ˜๋Š” password ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„, ์ „๋‹ฌ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•ด์‹œํ™”ํ•˜๊ณ  ์ €์žฅ๋œ passwordHash ๊ฐ’๊ณผ ๋น„๊ตํ•œ๋‹ค.

ํด๋กœ์ € ์งง๋ง‰ ์ƒ์‹

  • ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์ฑก์ฑก ์Œ“๊ธฐ
    • ํด๋กœ์ €๋Š” ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋  ๋‹น์‹œ์˜ lexical enviorment(์—ฌ๊ธฐ์„œ๋Š” passwordHash ๋ณ€์ˆ˜)์„ ๊ธฐ์–ตํ•˜์—ฌ, ๋‚˜์ค‘์— ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ์—๋„ ๊ทธ enviorment์˜ ๋ณ€์ˆ˜ ๊ฐ์ฒด์— ์ ‘๊ทผ
  • ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋ฐ ํ•„์š”ํ•œ execution context๋Š” ์Šคํƒ์—์„œ pop๋จ => passwordHash์— ์ ‘๊ทผํ•˜๋ ค๋ฉด, ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋˜ ์‹œ์ ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ์ฐธ์กฐํ•ด์•ผํ•จ(์ฆ‰, ํด๋กœ์ €๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ). ๋ณ€์ˆ˜ ๊ฐ์ฒด๋Š” ํ•จ์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜์ง€ ์•Š์œผ๋ฉด ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ๋˜ํ•œ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜์— ์˜ํ•ด ์ฐธ์กฐ๋˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฐ€๋น„์ง€ ์ปฌ๋ž™ํŒ…๋˜์ง€ ์•Š์Œ.

์˜ˆ์ œA์˜ ๋‹จ์ 

  • ๋ฉ”์„œ๋“œ ์ •์˜ ์œ„์น˜๊ฐ€ ์ œํ•œ์ : ์ƒ์„ฑ์ž ์™ธ๋ถ€์—์„œ passwordHash์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, passwordHash์— ์ ‘๊ทผํ•˜๋Š” ๋ฉ”์„œ๋“œ๋„ ์ƒ์„ฑ์ž ๋‚ด๋ถ€์— ์ •์˜๋˜์–ด์•ผ ํ•œ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ: ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋ฉ”์„œ๋“œ์˜ ๋ณต์‚ฌ๋ณธ์ด ์ƒ์„ฑ๋œ๋‹ค.
  • ๋™์ผ ํด๋ž˜์Šค์—์„œ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค: ์„œ๋กœ์˜ ๋น„๊ณต๊ฐœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ํด๋ž˜์Šค ๋‹จ์œ„ ๋น„๊ณต๊ฐœ? ์ผ๋ฐ˜์ ์ธ ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์—์„œ๋Š” ๋™์ผ ํด๋ž˜์Šค์˜ ๊ฐœ๋ณ„ ์ธ์Šคํ„ด์Šค๋ผ๋ฆฌ private ์†์„ฑ์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์˜ˆ์ œB: Private Class Fields

  • ECMAScript 2022 ํ‘œ์ค€, ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์™ธ๋ถ€์—์„œ๋Š” ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.
    • ์ด์ „ ๋ฒ„์ „์œผ๋กœ ์ปดํŒŒ์ผ ์‹œ WeapMap์œผ๋กœ ๋Œ€์ฒด๋จ
class PasswordChecker {
  #passwordHash: number;

  constructor(passwordHash: number) {
    this.#passwordHash = passwordHash;
  }

  checkPassword(password: string) {
    return hash(password) === this.#passwordHash;
  }
}

const checker = new PasswordChecker(hash("s3cret"));
checker.checkPassword("secret"); // false
checker.checkPassword("s3cret"); // true

WeapMap์ด๋ž€?

  • ๊ฐ์ฒด๋งŒ ํ—ˆ์šฉ
    • WeakMap์€ ํ‚ค๋กœ ๊ฐ์ฒด๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›์‹œ ์ž๋ฃŒํ˜•(์˜ˆ: ์ˆซ์ž, ๋ฌธ์ž์—ด ๋“ฑ)์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์•ฝํ•œ ์ฐธ์กฐ(Weak References)
    • WeakMap์€ ํ‚ค๋กœ ์‚ฌ์šฉ๋œ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์•ฝํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์•ฝํ•œ ์ฐธ์กฐ๋Š” ๋‹ค๋ฅธ ๊ณณ์—์„œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š์œผ๋ฉด, ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์˜ ๋Œ€์ƒ์ด ๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, WeakMap์˜ ํ‚ค๋กœ ์‚ฌ์šฉ๋œ ๊ฐ์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
// WeakMap์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋ผ์ด๋น— ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ ์˜ˆ์ œ
const privateData = new WeakMap();

// ํด๋ž˜์Šค ์ •์˜
class Person {
  constructor(name, age) {
    // WeakMap์— ํ˜„์žฌ ์ธ์Šคํ„ด์Šค(this)๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ €์žฅ
    privateData.set(this, { name: name, age: age });
  }

  // ํ”„๋ผ์ด๋น— ๋ฉ”์„œ๋“œ ์˜ˆ์‹œ: ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ
  #privateMethod() {
    console.log(`This is a private method for ${privateData.get(this).name}`);
  }

  // ๊ณต๊ฐœ ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋ผ์ด๋น— ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ ์˜ˆ์‹œ
  introduce() {
    // privateData๋ฅผ ํ†ตํ•ด ํ”„๋ผ์ด๋น— ๋ฐ์ดํ„ฐ ์ ‘๊ทผ
    const { name, age } = privateData.get(this);
    console.log(`Hello, my name is ${name} and I am ${age} years old.`);
    // ํ”„๋ผ์ด๋น— ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
    this.#privateMethod();
  }
}

// Person ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const person1 = new Person("Alice", 30);

// introduce ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
person1.introduce(); // ์ถœ๋ ฅ: Hello, my name is Alice and I am 30 years old.
//        This is a private method for Alice

// ์™ธ๋ถ€์—์„œ privateData์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ
console.log(privateData.get(person1)); // undefined

์š”์•ฝ

  • public, protected, private๊ฐ™์€ access modifiers๋Š” ํƒ€์ž… ์‹œ์Šคํ…œ์—๋งŒ ๊ฐ•์ œ๋จ.
    • ๋Ÿฐํƒ€์ž„์—๋Š” ์†Œ์šฉ์ด ์—†์œผ๋ฉฐ, ๋‹จ์–ธ๋ฌธ์œผ๋กœ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํด๋กœ์ € & ํ”„๋ผ์ด๋น— ํ•„๋“œ ์‚ฌ์šฉํ•˜๊ธฐ

์•„์ดํ…œ 57: ์†Œ์Šค๋งต์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋””๋ฒ„๊น…ํ•˜๊ธฐ

  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค: ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ƒ์„ฑํ•œ JS ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
    • ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋„๊ตฌ๋“ค ์˜ˆ์‹œ) ์••์ถ•๊ธฐ minifier๋‚˜ ์ „์ฒ˜๋ฆฌ๊ธฐ preprocessor
  • ๋””๋ฒ„๊ฑฐ๋Š” ๋Ÿฐํƒ€์ž„์— ๋™์ž‘ => ๋””๋ฒ„๊น…์„ ํ•˜๋ฉด ๋ณด๊ฒŒ๋˜๋Š” ์ฝ”๋“œ๋Š” ์ „์ฒ˜๋ฆฌ๊ธฐ, ์ปดํŒŒ์ผ๋Ÿฌ, ์••์ถ•๊ธฐ๋ฅผ ๊ฑฐ์นœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ์ด๋‹ค.
    • ๋ณ€ํ™˜๋œ JS๋Š” ๋ณต์žกํ•˜๋‹ค.

์†Œ์Šค๋งต source map

  • ๋ธŒ๋ผ์šฐ์ € ์ œ์กฐ์‚ฌ๊ฐ€ ๋‚ด๋†“์€ ํ•ด๊ฒฐ์ฑ…: ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €์™€ ๋งŽ์€ IDE๊ฐ€ ์ง€์›
  • ๋ณ€ํ™˜๋œ ์ฝ”๋“œ์˜ ์œ„์น˜์™€ ์‹ฌ๋ฒŒ๋“ค์„ ์›๋ณธ ์ฝ”๋“œ์˜ ์›๋ž˜ ์œ„์น˜์™€ ์‹ฌ๋ฒŒ๋กœ ๋งคํ•‘

๋ณ€ํ™˜๋œ JS ์˜ˆ์‹œ

  • async, await์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ƒํƒœ ๋จธ์‹ (state machine)์œผ๋กœ ์žฌ์ž‘์„ฑ

    • ์ฝ”๋“œ์˜ ๋™์ž‘์€ ๋™์ผํ•˜์ง€๋งŒ, ํ˜•ํƒœ๊ฐ€ ๋งค์šฐ ๋‹ค๋ฅด๊ฒŒ ๋œ๋‹ค.
    • tsconfig.json์—์„œ sourceMap ์„ค์ • => .ts ํŒŒ์ผ์— ๋Œ€์‘ํ•˜๋Š” .js์™€ .js.map ํŒŒ์ผ์„ ์ƒ์„ฑ
    {
      "compilerOptions": {
        "sourceMap": true
      }
    }
    
  • ์†Œ์Šค๋งต์ด js์™€ ํ•จ๊ป˜ ์žˆ์œผ๋ฉด? ๋ธŒ๋ผ์šฐ์ €์˜ ๋””๋ฒ„๊ฑฐ์—์„œ ์ƒˆ๋กœ์šด index.ts ํŒŒ์ผ์ด ๋‚˜ํƒ€๋‚จ => ๋ธŒ๋ ˆ์ดํฌํฌ์ธํŠธ ์„ค์ • & ๋ณ€์ˆ˜ ์กฐ์‚ฌ ๊ฐ€๋Šฅ

    • ๋””๋ฒ„๊ฑฐ ์ขŒ์ธก์˜ ํŒŒ์ผ ๋ชฉ๋ก์—์„œ ํŒŒ์ผ์ด ๊ธฐ์šธ์ž„ ๊ธ€๊ผด์ด๋‹ค? => ์›น ํŽ˜์ด์ง€์— ์‹ค์ œ๋กœ ์กด์žฌํ•˜๋Š” ํŒŒ์ผ์ด ์•„๋‹ˆ๋‹ค!
    • index.js.map ํŒŒ์ผ์ด ํŒŒ์ผ ๋‚ด์šฉ์„ ํฌํ•จํ•˜๊ฑฐ๋‚˜(์ธ๋ผ์ธ), ๋ณ„๋„์˜ index.ts ํŒŒ์ผ์„ ๊ฐ€์ง€๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Œ(์ฐธ์กฐ ํฌํ•จ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋กœ๋“œ)
  • ์•Œ์•„๋‘˜ ์ 

    • TS๊ฐ€ bundler๋‚˜ minifier๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด? ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ์••์ถ•๊ธฐ๊ฐ€ ๊ฐ์ž ์†Œ์Šค๋งต์„ ์ƒ์„ฑํ•œ๋‹ค.
      • ์ด์ƒ์ ์ธ ๋””๋ฒ„๊น… ํ™˜๊ฒฝ์ด ๋˜๋ ค๋ฉด ์ƒ์„ฑ๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•„๋‹Œ ์›๋ณธ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์†Œ์Šค๋กœ ๋งคํ•‘๋˜๋„๋ก ํ•  ๊ฒƒ
      • ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ TS ์ง€์›์ด๋ผ๋ฉด ๋ณ„๋„ ์„ค์ • ์—†์ด ๊ดœ์ฐฎ์ง€๋งŒ, ์•„๋‹ˆ๋ผ๋ฉด ์ถ”๊ฐ€ ์„ค์ • ํ•„์š”
    • ์ƒ์šฉ ํ™˜๊ฒฝ์— ์†Œ์Šค๋งต์ด ์œ ์ถœ๋˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ
      • ๋””๋ฒ„๊ฑฐ๋ฅผ ์—ด์ง€ ์•Š๋Š” ์ด์ƒ ์†Œ์Šค๋งต์ด ๋กœ๋“œ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ์„ฑ๋Šฅ ์ €ํ•˜๋Š” ์—†์Œ
      • ์›๋ณธ ์ฝ”๋“œ์˜ ๋ณต์‚ฌ๋ณธ์— ์ฃผ์„, ๋ฒ„๊ทธ ์ถ”์ ์„ ์œ„ํ•œ url๋“ฑ ๊ณต๊ฐœํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๋‚ด์šฉ์ด ์žˆ์„ ๊ฒƒ
    • NodeJS ๋””๋ฒ„๊น…์—๋„ ์†Œ์Šค๋งต ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ํƒ€์ž… ์ฒด์ปค๊ฐ€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „ ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋””๋ฒ„๊ฑฐ๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†๋‹ค. ์†Œ์Šค๋งต์„ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋””๋ฒ„๊น… ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.

Things to Remember

  • Don't debug generated JavaScript. Use source maps to debug your TypeScript code at runtime.
    • ์›๋ณธ ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ๋ณ€ํ™˜๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋””๋ฒ„๊น…ํ•˜์ง€ ๋ง๊ณ , ์†Œ์Šค๋งต์„ ์‚ฌ์šฉํ•ด์„œ ๋Ÿฐํƒ€์ž„์˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ๋””๋ฒ„๊น…ํ•˜์ž~!
  • Make sure that your source maps are mapped all the way through to the code that you run.
    • ์†Œ์Šค๋งต์ด ์™„์ „ํžˆ ๋งคํ•‘๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ๊ฒƒ
  • Know how to debug Node.js code written in TypeScript.
  • Depending on your settings, your source maps might contain an inline copy of your original code. Don't publish them unless you know what you're doing!
    • ์†Œ์Šค๋งต์— ์›๋ณธ ์ฝ”๋“œ๊ฐ€ ๊ทธ๋Œ€๋กœ ํฌํ•จ๋˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๊ณต๊ฐœํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ