Skip to content

Webpack 기반의 React & Typescript 환경 셋팅

KIM DAEUN edited this page Dec 2, 2024 · 1 revision

Webpack

💡 요약

  • esbuild-loader 사용
  • ForkTsCheckerWebpackPlugin 플러그인 설정
  • html, css, svg, env 등에 대한 플러그인 및 설정 추가

webpack 구성 상세

  • webpack.config.js

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
    const Dotenv = require("dotenv-webpack");
    
    module.exports = {
      entry: "./src/main.tsx",
      module: {
        rules: [
          {
            test: /\.(js|jsx|ts|tsx|mjs)$/,
            exclude: /node_modules/,
            loader: "esbuild-loader",
            options: {
              target: "es2020",
            },
          },
          {
            test: /\.svg$/i,
            issuer: /\.[jt]sx?$/,
            use: ["@svgr/webpack"],
          },
          {
            test: /\.css$/i,
            use: ["style-loader", "css-loader"],
          },
        ],
      },
      resolve: {
        extensions: [".js", ".jsx", ".ts", ".tsx", ".mjs"],
        alias: {
          "@": path.resolve(__dirname, "src/"),
          "@components": path.resolve(__dirname, "src/components/"),
          "styled-system": path.resolve(__dirname, "src/styled-system/"),
        },
      },
      output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "dist"),
        clean: true,
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: "./index.html",
          filename: "index.html",
        }),
        new ForkTsCheckerWebpackPlugin({
          async: false,
          typescript: {
            configFile: path.resolve(__dirname, "tsconfig.json"),
          },
        }),
        new Dotenv(),
      ],
    };
  • webpack.dev.js

    const { merge } = require("webpack-merge");
    const common = require("./webpack.config.js");
    
    module.exports = merge(common, {
      mode: "development",
      devtool: "eval-source-map",
      devServer: {
        historyApiFallback: true,
        port: 3000,
        hot: true,
      },
    });
  • webpack.prod.js

    const { merge } = require("webpack-merge");
    const common = require("./webpack.config.js");
    
    module.exports = merge(common, {
      mode: "production",
      devtool: "hidden-source-map", // 에러 보고 목적으로 소스맵을 사용할 때 선택
    });

공통 설정

loader

웹팩이 웹 애플리케이션을 빌드할 때, import 한 모든 웹 자원을 해석하기 위해 필요한 도구.

  • Babel vs ts-loader vs esbuild-loader 장단점 분석
    • Babel
      • 새로운 문법이나 타입스크립트 혹은 JSX로 작성된 코드가 모든 브라우저에서 동작할 수 있도록 하위 버전(ES5)의 자바스크립트 언어로 변환시켜주는 컴파일러.
      • 지원하는 기능이 많지만 개별 설치 및 세팅해야 하므로 번거로움이 있다.
      • 또한 ES6를 지원하지 않는 브라우저에서 사용하기 위한 목적이므로 크루루의 서비스 타겟층을 고려할 때 필요성이 크지 않다.
    • ts-loader
      • Webpack과 TypeScript 컴파일러를 통합하여 TypeScript 코드를 JavaScript로 변환하는 로더.
      • TypeScript 컴파일러를 사용하여 타입 검사와 코드 변환을 동시에 처리하기 때문에 타입 안정성을 지킬 수 있지만, 다른 도구에 비해 빌드 속도가 느려진다.
    • esbuild-loader
      • JavaScript 및 TypeScript 번들러이자 변환기.
      • CSS 및 기타 파일 변환도 지원하며, 설정이 간단하다.
      • 속도가 매우 빠르기 때문에 대규모 프로젝트에서 큰 장점을 갖는다.
      • 다만 TypeScript의 고급 타입 검사 기능 지원이 완벽하지 않으며, Babel이나 ts-loader에 비해 플러그인과 생태계가 작다.

웹 어플리케이션 특성 상 잦은 빌드 작업이 예상되는데, 이때 빌드 속도가 느리면 개발 경험이 크게 저해될 것으로 예상하여 속도가 가장 빠른 esbuild-loader 를 선택했다.

  • esbuild-loader 사용시 기본 boilerplate 빌드 속도 : 1.8초

image

  • ts-loader 사용시 기본 boilerplate 빌드 속도 : 3.6초

image

entry

Webpack이 번들링을 시작할 진입점

  • 프로젝트 구조에 따라 './src/main.tsx'로 설정했습니다.

module(rules)

  • JavaScript/TypeScript 파일 변환
    • .js, .jsx, .ts, .tsx, .mjs 파일을 esbuild-loader로 처리하여, ES2020 표준으로 변환합니다.
    • node_modules 폴더는 제외해 불필요한 파일 변환을 방지합니다.
  • SVG 파일 변환
    • svg 파일을 React 컴포넌트로 변환하기 위해 "@svgr/webpack” 을 사용합니다.
  • CSS 파일 변환
    • style-loader는 CSS를 DOM에 삽입하고, css-loader는 CSS 파일을 모듈로 변환합니다.

resolve

  • extensions
    • 파일 확장자를 생략할 수 있도록 설정합니다. 기입된 순서대로 해석합니다.
  • alias
    • 경로 별칭을 설정해 모듈 경로를 간결하게 만듭니다.

output

  • filename
    • 번들링된 파일의 이름을 bundle.js로 설정합니다.
  • path
    • 번들링된 파일을 저장할 디렉토리를 dist로 설정합니다.
  • clean
    • 빌드 시 이전 dist 디렉토리를 정리하여 깨끗한 상태를 유지합니다.

plugins

  • HtmlWebpackPlugin
    • index.html 파일을 템플릿으로 사용하여 최종 HTML 파일을 생성합니다. 이는 빌드된 JavaScript 파일을 자동으로 삽입합니다.
  • ForkTsCheckerWebpackPlugin
    • TypeScript 타입 검사를 별도의 프로세스로 처리하여 빌드 속도를 개선합니다. tsconfig.json 파일을 사용하여 TypeScript 설정을 적용합니다.
  • Dotenv
    • 환경 변수를 Webpack 빌드에 주입합니다.


TypeScript 환경 세팅

  • tsconfig.json

    {
      "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "forceConsistentCasingInFileNames": true,
    
        "target": "ES2020",
        "useDefineForClassFields": true,
        "lib": ["ES2020", "DOM", "DOM.Iterable"],
        "module": "ESNext",
        "skipLibCheck": true,
    
        /* Bundler mode */
        "moduleResolution": "Node",
        "resolveJsonModule": true,
        "isolatedModules": false,
        "noEmit": true,
        "jsx": "react-jsx",
    
        /* Linting */
        "strict": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "noFallthroughCasesInSwitch": true,
    
        /* Testing */
        "types": ["jest", "node"],
        "esModuleInterop": true,
    
        "baseUrl": "./",
        "paths": {
          "@/*": ["src/*"],
          "@components/*": ["src/components/*"],
          "styled-system/*": ["src/styled-system/*"]
        }
      },
      "include": ["src", "src/styled-system", "setupTests.ts"]
    }