리액트 SWC 프로젝트를 js에서 ts로 마이그레이션

JoonPark·2023년 11월 23일
0

리액트 템플릿

목록 보기
1/1
post-thumbnail

React + Webpack + SWC + TypeScript + tailwindCSS

  • 마이그레이션을 하며 거치는 과정을 배우는 것이 목표 (새로운 CRA로 ts 구성하지 않음)
  • 목표하는 프로젝트는 create-react-app으로 구성되지 않고 직접 package.json으로 의존성 구현.
  • react-dom, react-router-dom, swc, webpack과 같은 패키지를 yarn으로 설치했음
  • 타입스크립트는 기본적으로 개발단에서 쓰이는 것이기 때문에 항상 devDependencies에 설치되도록 yarn add -D 또는 npm install --save-dev 명령어로 설치한다.
  • PostCSS 플러그인을 사용해 TailwindCSS 스타일링을 Webpack에 세팅

1. 기존의 프리셋 프로젝트에서 Typescript 설치

  • 기존 프리셋 프로젝트의 package.json, .swcrc, webpack.config.js
// package.json
{
  "name": "react-webpack-swc",
	"author": "Joon Park",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server --mode development --open --hot",
    "build": "webpack --mode production"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.19.0"
  },
  "devDependencies": {
    "@swc/cli": "^0.1.59",
    "@swc/core": "^1.3.27",
    "@types/react": "^18.2.38",
    "@types/react-dom": "^18.2.16",
    "@types/react-router-dom": "^5.3.3",
    "html-webpack-plugin": "^5.5.0",
    "swc-loader": "^0.2.3",
    "typescript": "^5.3.2",
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1",
    "webpack-dev-server": "^4.11.1"
  }
}
// .swcrc
{
  "jsc":{
    "parser": {
      "syntax": "ecmascript",
      "jsx": true
    },
    "transform": {
      "react":{
        "runtime": "automatic"
      }
    },
  }
}
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.jsx',
  output: {
    path: path.join(__dirname, '/dist'),
    filename: 'index_bundle.js'
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    compress: true,
    port: 3000,
  },
  resolve: {
    extensions: ['.jsx', '.js', '.ts', '.tsx'],
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /(node_modules)/,
        use: {
            loader: "swc-loader"
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "./index.html",
      template: path.join(__dirname, 'public/index.html')
    })
  ]
}
  1. 아래 명령어를 터미널에서 입력해서 프로젝트에 타입스크립트와 바벨을 설치해준다
⚙ **`yarn add -D typescript fork-ts-checker-webpack-plugin HTMLWebpackPlugin @types/react @types/react-dom @types/react-router-dom`**

2. 타입스크립트 세팅 및 webpack 설정 변경

  • tsconfig.json 파일 생성 및 세팅
  • .swcrc 파일에 타입스크립트용 세팅 변경
  • webpack.config.js 파일 세팅 변경
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES6",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "incremental": true,
    "baseUrl": "src"
  },
  "include": [
    "src"
  ]
}
// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript", // TypeScript 문법을 사용하여 코드를 파싱합니다.
      "tsx": true, // TSX 문법(React와 함께 사용되는 TypeScript의 확장)을 활성화합니다.
      "decorators": false, // 데코레이터(클래스 및 메서드에 메타데이터를 추가하는 데 사용되는 TypeScript 기능)를 비활성화합니다.
      "dynamicImport": false // 동적 import 문을 비활성화합니다.
    },
    "transform": {
      "react": {
        "pragma": "React.createElement", // JSX 요소를 생성하는 데 사용되는 함수를 지정합니다.
        "pragmaFrag": "React.Fragment", // JSX 프래그먼트를 생성하는 데 사용되는 컴포넌트를 지정합니다.
        "runtime": "automatic", // JSX 변환을 위한 런타임을 자동으로 설정합니다.
        "throwIfNamespace": true, // JSX 네임스페이스가 허용되지 않을 경우 오류를 발생시킵니다.
        "development": false, // 개발 모드를 비활성화합니다.
        "useBuiltins": false // 내장된 헬퍼를 사용하지 않습니다.
      },
      "optimizer": {
        "globals": {
          "vars": {
            "__DEBUG__": "true" // __DEBUG__ 전역 변수를 true로 설정합니다.
          }
        }
      }
    }
  }
}
// webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  entry: './src/index.tsx',

  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'build'),
  },

  plugins: [
    new ForkTsCheckerWebpackPlugin(),
    new HTMLWebpackPlugin({
      template: './public/index.html',
    }),
  ],

  devServer: {
    static: path.resolve(__dirname, 'public'),
    historyApiFallback: true,
    hot: true,
    open: true,
    port: 3000,
  },

  resolve: {
    extensions: ['.jsx', '.js', '.ts', '.tsx'],
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        loader: 'swc-loader',
      }
    ],
  },
};

3. Tailwind 설치 및 세팅, webpack 설정 변경

  • 다음 명령어로 Tailwind 설치
⚙ `**yarn add -D tailwindcss postcss autoprefixer style-loader css-loader postcss-loader postcss-preset-env**`
  • tailwind.config.js 파일 생성 후 테일윈드 세팅
  • postcss.config.js 파일 세팅 변경
// tailwind.config.js
/** @type {import('tailwindcss').Config} */ // Tailwind CSS의 설정 타입을 import합니다.
module.exports = { // 모듈을 export합니다.
  content: ["./src/**/*.{html,js,jsx,ts,tsx}"], // Tailwind CSS가 스타일을 적용할 파일들을 지정합니다. 이 경우, src 디렉토리의 모든 html, js, jsx, ts, tsx 파일들을 대상으로 합니다.
  theme: { // 테마 설정을 시작합니다.
    extend: {}, // 기존 테마를 확장하는 설정을 추가합니다. 현재는 비어 있습니다.
  },
  plugins: [], // Tailwind CSS 플러그인을 추가하는 배열입니다. 현재는 비어 있습니다.
}
// postcss.config.js
module.exports = { // 모듈을 export합니다.
  plugins: { // PostCSS 플러그인을 추가하는 객체입니다.
    tailwindcss: {}, // Tailwind CSS 플러그인을 추가합니다. 현재는 추가 설정 없이 기본 설정을 사용합니다.
    autoprefixer: {}, // Autoprefixer 플러그인을 추가합니다. 이 플러그인은 CSS에 자동으로 vendor prefix를 추가합니다. 현재는 추가 설정 없이 기본 설정을 사용합니다.
  }
}
// webpack.config.js
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        loader: 'swc-loader',
      },
      {
        test: /\.css$/, // CSS 파일에 대한 정규식 패턴
        use: [
          'style-loader', // 스타일 태그를 생성하여 DOM에 적용
          'css-loader', // CSS를 CommonJS 모듈로 변환
          'postcss-loader' // postcss를 CSS로 컴파일
        ]
      }
    ],
  },
};

4. 실행 확인 및 리포지토리 최신화

  • yarn start 테스트 이상 없음

시행착오

  • 기존 babel js 리액트 프로젝트에서 typescript로 마이그레이션 해 본 경험이 있어서 ts마이그레이션은 쉬웠지만 오히려 Tailwind 설치와 세팅에서 애를 먹었다
  • css-loader가 없는 상황에서 TailwindCSS를 위해 설치하는 패키지만 해도 무려 7개…
  • 막상 설치 후에 webpack 설정은 sass 세팅과 비슷해서 쉽게 진행되었다.

연구 포인트

  • 웹팩 설정을 더 배워야겠다
profile
FE Developer

0개의 댓글