본문 바로가기
공부/리액트

기존 CRA 프로젝트에 TypeScript 추가하기

by 야옹아옹 2023. 3. 7.

메인 프로젝트를 진행 중, CRA로 이미 프로젝트 초기 구성을 해 놓은 상태에서 TypeScript를 사용하는게 어떻냐는 의견이 나왔다. 아직 prettier, eslint 정도만 설정해 놓았기 때문에 새로 CRA를 만드는 것이 편했지만, 이번 기회에 기존의 CRA에 TS를 추가해보기로 했다.

 

✨ CRA DOC 참고하기

CRA Doc는 매우 친절하게 모든 것을 알려주기 때문에, 꼭 궁금한 것이 있으면 찾아보는 것을 추천한다.

https://create-react-app.dev/docs/adding-typescript/#installation

 

Adding TypeScript | Create React App

Note: this feature is available with react-scripts@2.1.0 and higher.

create-react-app.dev

 

🧩 중간 섹션을 보면, 기존 CRA에 TypeScript를 추가하는 방법을 알려준다.

기존의 CRA에 typescript를 추가하는 방법

npm install --save typescript @types/node @types/react @types/react-dom @types/jest

물론 설치를 하고 바로 실행되면 좋겠지만, 바로 실행되지않는다.

 

🧩 index.js 를 index.ts/tsx로 변경하기

document.getElementById('root') 부분을 as HTMLElement

이 부분을 수정해주지않으면, 타입스크립트 에러가 난다. 그래서 index.ts 부분을 수정해야한다.

수정하지 않으면 나오는 에러 메시지

Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | DocumentFragment'. Type 'null' is not assignable to type 'Element | DocumentFragment'

 

🧩 tsconfig 파일 생성하기

타입스크립트 사용을 위해서 tsconfig 파일을 생성해야한다.

tsc --init 명령어를 사용하면 쉽게 tsconfig 파일을 생성 할 수 있다.

  • 해당 명령어를 사용하기 위해서는 global에 typescript를 설치해야한다.  npm install -g typescript

아래는 내가 사용한 tsconfig 파일

{
  "compilerOptions": {
  
    /* Language and Environment */
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    "jsx": "react-jsx",                                /* Specify what JSX code is generated. */
    
    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */
    
    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

tsconfig 파일 설정은 이곳에서 다루지 않음

 

🧩 reportWebVitals 에러 

TS7016: Could not find a declaration file for module './reportWebVitals'.

import reportWebVitals from './reportWebVitals'; 부분에서 에러가 난다. 따라서 reportWebVitals.js를 변경해주어야한다.

따라서, reportWebVitals.ts 로 변경해야한다. 변경할 때, 타입 에러가 나기 때문에 타입을 추가해 주어야한다.

import { ReportHandler } from 'web-vitals';

const reportWebVitals = (onPerfEntry?: ReportHandler) => {
  if (onPerfEntry && onPerfEntry instanceof Function) {
    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(onPerfEntry);
      getFID(onPerfEntry);
      getFCP(onPerfEntry);
      getLCP(onPerfEntry);
      getTTFB(onPerfEntry);
    });
  }
};

export default reportWebVitals;

문제는 ReportHandler가 에러가 나는 경우가 있다. 이 경우에는 package.json을 확인해서 web-vitals버전을 확인한다.

만약에, web-vitals의 버전이 "^2.1.4" 보다 높으면 ReportHandler가 deprecated 됬다고 뜨기 때문에 사용이 되지않는다.

 

🧩 기존에 사용하던 ESLint와 에러가 나지 않도록 설정하기

기존에 ESLint를 사용했다면, npm run start 시, 에러가 나면서 실행되지 않는다. ESLint 에러의 경우 에러 코드 내에 ESLint라는 글자가 있으니 참고하자.

나같은 경우는 기존에 설치한 ESLint 플러그인 중에 import 관련 부분이 충돌을 일으켜서 실행이 되지않았다.

https://github.com/typescript-eslint/typescript-eslint

 

GitHub - typescript-eslint/typescript-eslint: Monorepo for all the tooling which enables ESLint to support TypeScript

:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript - GitHub - typescript-eslint/typescript-eslint: Monorepo for all the tooling which enables ESLint to support TypeS...

github.com

 

위 사이트를 참고하면 쉽게 Typescript 환경에 ESLint를 적용할 수 있다.

 

Typescript에서 ESLint를 사용하기 위해 설치해야하는 라이브러리

npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint typescript

eslint와 typescript는 이미 설치가 되어있다면 제외시키면 된다.

설치하는 라이브러리에 대한 설명

@typescript-eslint/parser

- Typescript 파일을 파서할 때 ESLint가 사용하는 패키지. 필수이다. 

 

@typescript-eslint

- 내 코드에 적용할 기본 typescript-eslint 규칙들을 가진 라이브러리이다.

📢 따라서 위 두가지 패키지만 설치한다면, Typescript에 ESLint가 적용이 가능하다. 그외 React나 기타 등등은 필요한 것들과 충돌이 나지 않도록 설정해준다.

아래는 내가 사용한 ESLint 파일

// JSON
{
  "parser": "@typescript-eslint/parser", // ts
  // 환경
  "env": {
    "browser": true,
    "es2021": true
  },
  // 플러그인 사용
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    // "plugin:import/recommended", // TS랑 충돌이 나서 주석 처리
    "plugin:jsx-a11y/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  // lint가 이해할 수 있는 언어가 JS밖에 없기때문에 다른 확장 문법 사용 시, 파서를 사용하도록 설정해야한다.
  "parserOptions": {
    // ECMAScript의 언어 확장 기능 설정
    "ecmaFeatures": {
      "jsx": true // JSX 사용 여부
    },
    "ecmaVersion": "latest", // ECMAScript 버전
    "sourceType": "module" // 파서의 export 형태
  },

  // 사용할 규칙 설정, 0-off, 1-warn, 2-error
  "rules": {
    "react/react-in-jsx-scope": 0,
    "react/jsx-uses-react": 0,
    "react/prop-types": 0,
    "no-unused-vars":0
  },
  "settings": {
  }
}

 

🧩 'React' refers to a UMD global, but the current file is a module 에러

위 에러가 나타나는 경우에는 tsconfig.json에서 "jsx"를 "react-jsx"로 변경해주면 된다.

 

 

댓글