webpack으로 TypeScript 컴파일하기

aken·2025년 3월 21일
0

compiler? transpiler?

compiler

In computing, a compiler is a computer program that translates computer code written in one programming language (the source language) into another language (the target language). - wiki

compiler는 작성된 코드의 언어를 다른 언어로 변환하는 도구입니다. 언어를 변환하는 과정을 compile이라고 합니다.

compile은 주로 사람이 이해하는 프로그래밍 언어(고수준 언어)를 컴퓨터에서 실행하기 위해선 컴퓨터가 이해할 수 있는 언어(저수준 언어)로 변환하는 과정을 칭할 때 사용됩니다. 하지만, 무조건 저수준의 언어로 바꿔야 compile로 말하는 것은 아닙니다.

The name "compiler" is primarily used for programs that translate source code from a high-level programming language to a low-level programming language (e.g. assembly language, object code, or machine code) to create an executable program.

transpiler

A source-to-source translator, source-to-source compiler (S2S compiler), transcompiler, or transpiler is a type of translator that takes the source code of a program written in a programming language as its input and produces an equivalent source code in the same or a different programming language. - wiki

transpiler란 특정 프로그래밍 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 프로그래밍 언어의 소스 코드로 변환하는 도구입니다. source-to-source compiler라고도 불리며, compiler의 일종으로 볼 수 있습니다. 다시 말해, compiler은 transpiler보다 더 포괄적인 의미를 가집니다.

예) TypeScript -> JavaScript, ES2015 -> ES2009

babel은 compiler? transpiler?

babel오래된 브라우저와의 호환을 위해 ES2015+ 코드를 이전 버전의 코드로 변환합니다.

예를 들면, ES2015의 기능 중 하나인 화살표 함수를 함수 선언문으로 변경됩니다.

// Babel Input: ES2015 arrow function
[1, 2, 3].map(n => n + 1);

// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
  return n + 1;
});

비슷한 수준의 언어로 변경됐는데 transpiler라고 봐도 되지 않을까 하는 생각이 들었습니다.
stackoverflow에 "Is Babel a compiler or transpiler?" 질문이 있었는데, 답변으로 'babel은 source-to-source compiler, 일명 transpiler이다.'라고 달렸습니다.
즉, transpiler은 compiler에 포함되기 때문에, babel를 유연하게 받아들이면 compiler라고 할 수 있습니다.

TypeScript compiler

현재 프로젝트는 React와 TypeScript로 구현되어 있고, webpack으로 프로젝트 환경을 설정했습니다.
이 환경에서 어떤 compiler를 선택하면 좋을지 테스트해보려고 합니다.

TypeScript compiler

TSC(TypeScript compiler)은 TypeScript 코드를 JavaScript 코드로 컴파일합니다.

webpack 환경에서 TSC로 컴파일 하기 위해서 ts-loader가 필요합니다.

npm install --save-dev typescript ts-loader

설치가 완료됐다면, webpack.config.js와 tsconfig.json을 설정해야 하는데요.
webpack 공식문서을 참고하였습니다.

우선, webpack.config.js를 아래와 같이 설정해줍니다.

module.exports = {
  entry: './src/index.ts',
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

그런 다음 tsconfig.json에 compileOptions를 설정해줍니다.

{
  "compilerOptions": {
    "target": "ES5", /* TS 코드를 어떤 ECMAScript 버전의 자바스크립트로 변환할지 결정 */
    "module": "ESNext", /* 컴파일된 JS 코드가 어떤 모듈 시스템을 따를 것인지 결정 */
    "jsx": "react-jsx", /* JSX 구문을 어떻게 변환할지 */
    "esModuleInterop": true, /* CommonJS 모듈을 ES2015 모듈 스타일로 가져오기 위해 true로 설정 */
    "allowJs": true, /* JS도 컴파일 대상에 포함하기 위해 true로 설정*/
    "outDir": "./dist", /* 컴파일된 결과물이 저장될 디렉토리 */
    "strict": true, /* 엄격한 타입 검사 */
    "moduleResolution": "node", /*  컴파일러가 코드 내의 import 구문으로 참조된 모듈을 어떻게 찾을지 결정 */
    "sourceMap": true, /* 변경된 JS 코드가 TS의 어디에 해당하는지 알려줌 => 디버깅 용이 */
  },
  "include": ["src/**/*", "./declaration.d.ts"], /* 컴파일할 파일 지정 */
  "exclude": ["node_modules"] /* 컴파일 대상에서 제외할 파일 지정 */
}

tsconfig의 컴파일 옵션들은 굉장히 많으므로 공식문서를 보고 커스텀해보시는 걸 추천드립니다.

ts-loader는 트랜스파일과 타입 검사를 동시에 진행하기 때문에 빌드 속도가 느립니다.
이를 개선하기 위해 fork-ts-checker-webpack-plugin를 사용하면 좋습니다. 이 플러그인은 타입 검사를 별도의 프로세스에게 맡겨 빠르게 빌드할 수 있습니다.

// webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        // add transpileOnly option if you use ts-loader < 9.3.0 
        // options: {
        //   transpileOnly: true
        // }
      }
    ]
  },
  plugins: [new ForkTsCheckerWebpackPlugin()],
};

fork-ts-checker-webpack-plugin 적용 전

fork-ts-checker-webpack-plugin 적용 후

제 프로젝트에서 적용해보니 빌드 시간이 약 1초 정도 단축되었습니다.

babel

babel은 ECMAScript 2015+ 코드를 이전 버전의 브라우저에서 호환되는 JavaScript 코드로 변환합니다.

babel를 사용하기 위해 관련 라이브러리를 설치해줍니다.

npm i -D @babel/core @babel/preset-env @babel/preset-typescript @babel/preset-react babel-loader

그리고 아래와 같이 webpack과 babel를 설정해주시면 됩니다.

// webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'babel-loader',
      }
    ]
  },
};
// .babelrc
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-typescript",
    "@babel/preset-react"
  ],
}

TSC와 다르게 babel은 type을 확인하지 않습니다.

Keep in mind that Babel doesn't do type checking; you'll still have to install and use Flow or TypeScript to check types. - babel

아래 코드처럼 타입 에러가 발생해도, build할 때 에러가 발생하지 않습니다.

const a: number = "hello"; // type 에러 발생
console.log(a);

참고

What is TypeScript
babel 공식문서
바벨과 타입스크립트의 아름다운 결혼
타입스크립트 컴파일 설정 - tsconfig 옵션 총정리
TypeScript의 기본개념과 환경설정

0개의 댓글