Module

zimablue·2023년 8월 19일

typescript

목록 보기
15/18

Non-modules

TypeScript는 export나 최상위 await가 없는 JavaScript 파일을 모듈이 아닌 스크립트로 간주한다고 선언합니다.
또한 스크립트 안에서 작업할 때 변수와 타입은 공유 전역 스코프 내부에 있다고 선언됩니다.
모든 코드가 한 전역 스코프(global scope)에 있다고 간주한다는 의미입니다.

//utils.ts

function add(x: number, y: number) {
  return x + y;
}

function sample<T>(arr: T[]): T {
  const idx = Math.floor(Math.random() * arr.length);
  return arr[idx];
}

const x = 1;

다른 파일에 작성된 코드이지만 함수를 부를 때 문제가 생기지 않습니다.
하지만 const를 두 번 선언하자 문제가 발생합니다.

// index.ts

add(1, 2)

sample([12, 3, 34])

// Cannot redeclare block-scoped variable 'x'
const x = 2





Modules

모든 코드가 같은 스코프에 있는 것은 변수를 선언할 때 다른 파일에서 정의한 이름과 같거나 다른 파일과 같은 이름의 함수를 정의하는 것은 자주 일어날 수 있으며, 이는 문제가 될 수 있습니다.

TypeScript는 export 키워드를 넣어 두는 순간 모듈(module)에서 작업한다고 인식하기 시작합니다.

//utils.ts

export function add(x: number, y: number) {
  return x + y;
}

export function sample<T>(arr: T[]): T {
  const idx = Math.floor(Math.random() * arr.length);
  return arr[idx];
}
// index.ts

// Cannot find name 'add'
add(1, 2)

// Cannot find name 'sample'
sample([12, 3, 34])

export를 사용하면 각 파일이 각자 독립된 파일과 네임스페이스로 분리되어, 공유하려는 함수 기능을 일일이 가져오고 내보내야 합니다.
import할 때 유의 해야할 사항은 파일명이 .ts가 아니라 .js로 해야합니다.

//utils.ts

export function add(x: number, y: number) {
  return x + y;
}

export function sample<T>(arr: T[]): T {
  const idx = Math.floor(Math.random() * arr.length);
  return arr[idx];
}
// index.ts

import { add, sample } from "./utils.js";

add(1, 2)

sample([12, 3, 34])





컴파일 모듈 시스템 변경

export 키워드를 사용한 TypeScript는 CommonJS로 컴파일링 합니다.
하지만 브라우저 내 JavaScript는 CommonJS 모듈을 이해하지 못해서 exports 키워드가 무엇인지도 모르고 모듈도, require 키워드도 이해하지 못합니다.
따라서 tsconfig.json파일에서 import와 export가 있는 ES Module을 사용하도록 설정을 해야 합니다.

// tsconfig.json

{
    "compilerOptions": {
      "module": "ES6"
    }
}

index.htmltypemodule로 바꾸어 줍니다.

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Modules</title>
  </head>
  <body>
    <script type="module" src="./dist/index.js"></script>
  </body>
</html>





import type

TypeScript에서는 파일끼리 타입을 공유할 수 있습니다.
컴파일링된 JavaScript에서 import type은 사라집니다.

// types.ts

export interface Person {
  username: string;
  email: string;
}

export type Color = "red" | "green" | "blue";
// User.ts

//(alias) interface Person
import type { Person } from "./types.js";
export default class User implements Person {
  constructor(public username: string, public email: string) {}
  logout() {
    console.log(`${this.username} logs out`);
  }
}

export function userHelper() {
  console.log("USER HELPER!");
}

아래와 같이 작성하면 타입이 아닌 모듈과 함께 사용할 수 있습니다.

import { type Person, 타입이아닌다른모듈 } from "./types.js";
export default class User implements Person {
  constructor(public username: string, public email: string) {}
  logout() {
    console.log(`${this.username} logs out`);
  }
}

export function userHelper() {
  console.log("USER HELPER!");
}

0개의 댓글