Just Do IT!

[Typescript] Webpack + typescript 환경 설정하기 본문

개발 공부/TypeScript

[Typescript] Webpack + typescript 환경 설정하기

MOON달 2023. 1. 31. 21:02
728x90
Webpack이란?
  • 파일을 묶는(bundle) 것을 도와주는 도구
  • bundling & building & orchestration (묶고 빌드하고 종합하는 도구) ⇒ 코드를 묶음으로써 Http 요청의 양을 줄이는 걸 도와준다
  • 코드를 최적화하고 빌드 절차를 추가하고, 추가 빌드 툴을 제공한다

  • 코드를 묶어서 import를 덜 할 수 있게 해준다
  • 코드를 최적화하여 적은 코드를 싣게 하고 사용자들이 적은 코드를 다운로드 할 수 있게 해준다
  • 원하면 개발 서버를 추가할 수 있다

공식 문서에 더 정확한 설명이 적혀있으니 공식 문서를 읽어보는 것이 더 좋다.

https://webpack.js.org/

 

webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

 

 

 

 

 

 

 

 

Webpack 설치하기
$ npm install --save-dev webpack webpack -cli webpack-dev-server typescript ts-loader
  • webpack : 코드를 묶고(bundle) 변환하기 위한 특정 기능을 플러그인 하도록 해준다
  • webpack-cli : 프로젝트에서 웹팩 명령어를 실행하려면 필요
  • webpack-dev-server : 개발 서버 내에서 빌드하기 위해서 필요 (파일의 변경사항을 점검하고 무언가 변경이 생겼을 때 웹페이지의 재컴파일을 시작)
  • typescript : 이미 글로벌로 설치했지만 프로젝트마다 typescript의 사본을 설치하는 건 좋은 관행이다
  • ts-loader : 웹팩과 함께 동작할 패키지 ⇒ 웹팩에게 어떻게 코드를 자바스크립트로 변환할 것인지를 전달

 

 

 

 

 

 

tsconfig.json 파일 수정
// tsconfig.json
"target": "es6"  // es6 혹은 es5로 되어있는지 확인
"module": "es2015"  // es2015 or es2016

...

"sourceMap": true  // true로 되어 있는지 check

...

// "rootDir": "./src"  root dir 필요 x => webpack이 루트 파일 위치를 결정할 것이기 때문

☞ 이건 내가 유데미 강의를 들으면서 수정했던 부분이고 공식 문서에는 아래와 같이 되어 있다.

 

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "moduleResolution": "node"
  }
}

 

  • webpack이 루트 파일의 위치를 결정하기 때문에 더 이상 rootDir이 필요하지 않는다
  • sourceMap : 웹페이지 검사를 했을 때 source 탭에서 코드를 보고 수정할 수 있게 만든다.

 

 

 

 

 

 

webpack의 프로젝트 분석 순서
  1. 시작 지점(entry point)이 어디인가 파악
  2. 이 파일 내의 import를 파악
  3. 그 파일들로 가서 import를 파악 (import된 파일의 import를 살펴보는 방식) ⇒ 프로젝트의 모든 파일을 파악할 때까지 진행
  4. 파일 내용(contents)를 파악 (모든 파일의 내용)
  5. ts-loader 패키지의 도움을 받아서 컴파일

 

 

 

 

 

 

webpack.config.js 파일 생성 (webpack 설정 파일)

공식문서에 적혀 있는 webpack.config.js 파일 예제

const path = require('path');

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

=> webpack이 ./index.ts 를 통해 진입하고, ts-loader를 통해 모든 .ts  .tsx 파일을 로드한다.

      현재 디렉터리에 bundle.js파일을 출력

 

 

유데미 강의 들으면서 만들었던 프로젝트의 webpack.config.js 파일

const path = require("path");
// dist 폴더로의 절대 경로를 구축하고 웹팩이 그걸 사용하여 출력을 쓰게 된다

module.exports = {
  // 진입 속성 (시작 시점 파악)
  entry: "./src/app.ts",
  output: {
    // 마지막으로 생성되는 단일 자바스크립트 파일
    filename: "bundle.js",
    // 출력이 쓰여지는 경로 명시
    path: path.resolve(__dirname, "dist"),
  },

  // sourceMap => 코드의 디버그 지원(tsconfig.json 파일에도 있음) 웹팩에서도 지원
  devtool: "inline-source-map",
  // 기본적으로 생성한 bundle을 추출하고 정확하게 접속해야 하는 생성된 source map이 이미 존재한다는 것을 웹팩에게 전달
  // bundle를 생성하면서 좋은 개발 경험을 쌓을 수 있다.

  // typescript로 무얼 할지 웹팩에게 전달하기 위해서 configuration object에 entry 새로 추가
  // module 이 자바스크립트 object를 취하여 configure한다
  module: {
    // rules 배열 => 모든 파일에 적용될 여러 개의 법칙들 설정 가능
    rules: [
      // webpack에게 특정 파일을 어떻게 다룰지 전달해주는 패키지
      {
        // 규칙이 해당 파일에 적용되는지 여부를 알기 위함
        test: /\.ts$/, // 정규 표현식 (파일 확장자를 점검)
        use: "ts-loader", // test에 이용할 것들
        exclude: /node_modules/, // webpack이 node module을 찾지 않음
      },
    ],
  },
  // import에 추가할 파일 확장자를 웹팩에 전달
  resolve: {
    // .ts 파일, .js 파일을 찾아야 한다고 알렺무
    extensions: [".ts", ".js"],
  },
};

 

 

  • entry : 진입 속성 (시작 시점 파악)
  • output : 마지막으로 생성되는 단일 자바스크립트 파일 (보통 bundle.js)
  • path : 출력이 쓰여지는 경로 명시 (dist 폴더)
  • devtool : 기본적으로 생성한 bundle를 추출하고 정확하게 접속해야 하는 source map을 webpack에 전달
  • module : typescript로 무엇을 할지 전달하기 위함
  • rules : 모든 파일에 적용될 여러 개의 법칙들 설정 가능
  • test: 정규 표현식으로 파일 확장자 점검
  • exclude: webpack이 제외할 폴더/파일 설정
  • resovle : import에 추가할 파일 확장자를 웹팩에 전달

 

 

 

 

 

 

 

package.json 와 index.html 파일 수정
  • package.json 파일에서 스크립트 추가
    • npm run build 시 웹팩 작동
    "scripts": {
        "test": "echo \\"Error: no test specified\\" && exit 1",
        "start": "lite-server",
        "build": "webpack"   // build 추가
      },
    
  • index.html 파일에서 import를 bundle.js 로 변경
    • npm start 로 프로젝트 빌드하여 index.html 불러와서 확인하기
<script type="module" src="dist/bundle.js"></script>
  • 개발자 도구에서 Source 탭의 webpack 폴더에 들어가면 타입스크립트 코드를 볼 수 있다 = source map

 

 

 

 

 

 

webpack-dev-server (development workflow)
    • localhost:8080 상에서 동작
    • 웹팩 빌드 워크플로우를 동작시킨다
    • 파일에서 변경해도 콘솔에 로그가 남지 않는다
    • 번들은 메모리에서만 생성된다 (정확하게 연결되어 있지는 않음) ⇒ webpack.config.js 파일에서 output에 publicPath를 입력하고 dist로 설정해야 한다.
// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server",
    "build": "webpack"
  },
// webpack.config.js

module.exports = {
  // 웹팩 데브 서버를 재구성하기 위해 필요한 코드 (개발 워크플로우)
  mode: "development",
  // 진입 속성 (시작 시점 파악)
  entry: "./src/app.ts",
  output: {
    // 마지막으로 생성되는 단일 자바스크립트 파일
    filename: "bundle.js",
    // 출력이 쓰여지는 경로 명시
    path: path.resolve(__dirname, "dist"),
    /* 
    출력이 어디에 쓰여지고 index.html 파일과 비교해서
    어디에 있는지 실제로 이해하기 위해 웹페이지 데브 서버에 필요한 추가 구성
     */
    publicPath: "dist",
  },

...

 

 

 

 

 

 

webpack.config.prod.js (production workflow)
  • webpack.config.prod.js 파일 생성
  • 웹팩 스크립트를 실행하고 생성한 출력을 지역적으로 실행되는 서버에 임시로 제공하는 것이 아니라 dist에 작성할 것
  • devtool을 none으로 설정하여 소스맵(sourcemap) 생성 X (필요 없음)
  • 새로운 출력이 쓰여지기 전에 dist 폴더 내의 모든 것을 자동으로 삭제하는 플러그인 추가 ⇒ plugin 설치 필요
$ npm install --save-dev clean-webpack-plugin
// webpack.config.prod.js
const path = require("path");
// dist 폴더로의 절대 경로를 구축하고 웹팩이 그걸 사용하여 출력을 쓰게 된다

// plugin import
const CleanPlugin = require("clean-webpack-plugin");

module.exports = {
  // webpack에게 최적화, 코드 경량화 등을 지시하는 mode
  mode: "production",
  // 진입 속성 (시작 시점 파악)
  entry: "./src/app.ts",
  output: {
    // 마지막으로 생성되는 단일 자바스크립트 파일
    filename: "bundle.js",
    // 출력이 쓰여지는 경로 명시
    path: path.resolve(__dirname, "dist"),
  },

  // sourceMap => production 모드에서는 필요하지 않음
  devtool: "none",
  // 기본적으로 생성한 bundle을 추출하고 정확하게 접속해야 하는 생성된 source map이 이미 존재한다는 것을 웹팩에게 전달
  // bundle를 생성하면서 좋은 개발 경험을 쌓을 수 있다.

  // typescript로 무얼 할지 웹팩에게 전달하기 위해서 configuration object에 entry 새로 추가
  // module 이 자바스크립트 object를 취하여 configure한다
  module: {
    // rules 배열 => 모든 파일에 적용될 여러 개의 법칙들 설정 가능
    rules: [
      // webpack에게 특정 파일을 어떻게 다룰지 전달해주는 패키지
      {
        // 규칙이 해당 파일에 적용되는지 여부를 알기 위함
        test: /\\.ts$/, // 정규 표현식 (파일 확장자를 점검)
        use: "ts-loader", // test에 이용할 것들
        exclude: /node_modules/, // webpack이 node module을 찾지 않음
      },
    ],
  },
  // import에 추가할 파일 확장자를 웹팩에 전달
  resolve: {
    // .ts 파일, .js 파일을 찾아야 한다고 알렺무
    extensions: [".ts", ".js"],
  },
  // 규칙과 모듈은 구체적으로 파일 레벨 별로 적용된다

  // plugins (추가 확장자 플러그인)
  // 일반적인 워크플로우에 적용된다
  // 새로운 출력이 쓰여지기 전에 dist 폴더 내의 모든 것을 자동으로 삭제하는 플러그인 추가
  plugins: [new CleanPlugin.CleanWebpackPlugin()],
};
  • package.json에서 빌드 스크립트 조정
"scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1",
    "start": "webpack-dev-server",
    "build": "webpack --config webpack.config.prod.js"
  },

 

 

 

 

 

 

 

 

 


유데미 강의 section 중 TypeScript와 함께 Webpack 사용하기 강의를 듣고 정리해봤다.

프로젝트를 따라치면서 한 거라 다시 봐야할 것들이 많다. 공식 문서에 제대로 나와있으니 복습해야지.

 

혹시나 이글 타고 들어오신 분들도....꼭 공식문서 참고하시길...

 

https://webpack.kr/guides/typescript/

 

TypeScript | 웹팩

웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.

webpack.kr

 

 

이건 typescript 핸드북에 나와 있는 부분.

https://typescript-kr.github.io/pages/tutorials/react-&-webpack.html

 

TypeScript 한글 문서

TypeScript 한글 번역 문서입니다

typescript-kr.github.io