[React] TypeScript + Prettier + ESLint(airbnb) 프로젝트 설정

문지은·2023년 9월 6일

React + TypeScript

목록 보기
1/2
post-thumbnail

타입스크립트 리액트 프로젝트 생성

생성한 리액트 프로젝트에 타입스크립트 적용하기

  • create-react-app으로 생성한 리액트 프로젝트에 타입스크립트를 적용하는 방법
npx create-react-app [프로젝트명]
npx create-react-app my-app
  • create-react-app으로 생성한 리액트 프로젝트에 타입스크립트를 적용하기 위해서는 타입스크립트 라이브러리와 리액트의 타입이 정의된 타입 정의 파일을 설치할 필요가 있음
  • 다음 명령어를 사용하여 타입스크립트와 타입 정의 파일을 설치
# cd my-app
npm install --save-dev typescript @types/node @types/react @types/react-dom
  • 이때 설치한 라이브러리와 타입 정의 파일은 다음과 같음
    • typescript : 타입스크립트 라이브러리
    • @types/node : 자바스크립트 런타임인 노드의 타입이 정의된 타입 정의 파일
    • @types/react : 리액트의 타입이 정의된 타입 정의 파일
    • @types/react-dom : react-dom의 타입이 정의된 타입 정의 파일
  • 이제 프로젝트에 타입스크립트를 설정하기 위해 tsconfig.json 파일을 생성해야 함.
    • tsconfig.json 파일은 타입스크립트 프로젝트를 컴파일하기 위한 여러 가지 옵션을 설정할 수 있는 파일
    • 타입스크립트는 빌드 과정이 필요하고 빌드 결과물로 자바스크립트 파일들이 생성
    • tsconfig.json 파일에 대한 자세한 내용은 공식 문서 참고
  • tsconfig.json 파일을 프로젝트 루트 폴더(/my-app/tsconfig.json)에 생성하고 다음 내용을 추가
{
  "compilerOptions": {
    "target": "es5",
    "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"
  },
  "include": [
    "src",
    "custom.d.ts"
  ]
}
  • 혹시 다음과 같은 오류가 뜬다면 compilerOptions의 jsx 옵션이 “react”로 설정되어 있지 않은지 확인
    • react-jsx 또는 react-jsxdev로 변경

  • 각 옵션에 대한 의미는 다음과 같음
{   //compilerOptions 속성은 생략될 수 있으며 생략하면 컴파일러의 기본 값이 사용됨.
    "compilerOptions": {
      "target": "es5", //타입스크립트 파일을 어떤 버전의 자바스크립트로 바꿔줄지 정하는 부분(기본값)
      // 커스텀하게 라이브러리를 쓰려고 할 때 lib 정의. 여기에 항목을 정하지 않았다면 target에서 지정한 기본값 버전에 따라 정의됨.
      "lib": [
        "dom",
        "dom.iterable",
        "esnext"
      ], 
      "allowJs": true, //true 라면 파일의 확장자가 .js, .jsx 사용 가능. 기본은 .ts, .tsx 및 .d.ts
      "skipLibCheck": true, // 선언 파일의 유형 검사를 건너뛰어 컴파일하는 동안 시간을 절약할 수 있음.
      "esModuleInterop": true, // ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있게 됨. (import 를 require로 사용할 수 있음. 아니면 import * as 로도 사용 가능.)
      "allowSyntheticDefaultImports": true, // default export 가 아닌 모듈에서도 default import 가 가능하게 할 지에 대한 여부. 타입 확인에 영향.
      "strict": true, // strict 모드 활성화 여부
      "forceConsistentCasingInFileNames": true, // 같은 파일에 대한 일관되지 않은 참조를 허용하지 않을 지에 대한 여부
      "noFallthroughCasesInSwitch": true, //switch 문에서 fallthrough 케이스에 대한 에러보고 여부
      "module": "esnext", // 모듈을 위한 코드 생성 설정 (none, commonjs, amd, system, umd, es2015, es2020 or esnext)
      "moduleResolution": "node", // 모듈 해석 방법 설정: 'node' (Node.js) 혹은 'classic' (TypeScript pre-1.6).
      "resolveJsonModule": true, //ts 는 기본적으로 json 파일 확인을 지원하지 않음. json 파일을 가져오기 위한 설정
      "isolatedModules": true, // 각 파일을 분리된 모듈로 트랜스파일
      "noEmit": true, //결과 파일을 내보낼지에 대한 여부
      "jsx": "react-jsx" // JSX 코드 생성 설정 (preserve, react-native, 혹은 react-jsx)
    },
    "include": [
      "src"  // 프로그램에 포함할 파일 이름 또는 패턴의 배열을 지정. (src/**/*, tests/**/*) 예시처럼 해당 파일이 가진 디렉토리를 기준으로 확인됨.
    ]
  }
  • 타입스크립트 설정을 끝냈다면, 자바스크립트 파일들을 타입스크립트 파일로 변경
    • ./src/App.js./src/App.tsx
    • ./src/App.test.js./src/App.test.tsx
    • ./src/index.js./src/index.tsx
    • ./src/reportWebVitals.js./src/reportWebVitals.ts
    • ./src/setupTests.js./src/setupTests.ts
  • 여기서 .tsx 파일은 TypeScript JSX 파일을 의미하고, .ts 파일은 TypeScript JavaScript 파일을 의미
  • 이렇게 .js 파일 확장자를 .tsx 또는 .ts로 수정하면 TypeScript가 에러를 출력
    • 기존의 자바스크립트 코드를 타입스크립트를 사용하여 변경하여야 함
  • ./src/index.tsx 수정
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • reportWebVitals.ts 수정
import type { ReportHandler } from 'web-vitals/dist/modules/types';

const reportWebVitals = (onPerfEntry?: ReportHandler) => {
...
  • svg 파일을 타입스크립트에서 불러올 수 있게 하기 위해 ./src/custom.d.ts 파일을 생성하고 다음과 같이 수정
declare module '*.svg' {
  import * as React from 'react';

  export const ReactComponent: React.FunctionComponent<React.SVGProps<
    SVGSVGElement
  > & { title?: string }>;

  const src: string;
  export default src;
}
  • 모든 설정이 끝나면 리액트 프로젝트가 잘 실행되는지 확인
npm start

  • create-react-app을 사용하는 이유는 React로 프로젝트를 만들때, 많은 설정들을 하지 않기 위함인데, 위와 같은 방법을 사용하면 TypeScript만을 위해 너무 많은 설정이 필요함.
  • create-react-app 에서는 TypeScript의 중요성을 인지 하고 TypeScript를 더욱 간단하게 지원하기 위해 Template 옵션을 제공

타입스크립트 템플릿 사용하기

  • 아래 명령어를 실행하여 타입스크립트가 적용된 리액트 프로젝트를 간단하게 생성할 수 있음.
npx create-react-app [프로젝트명] --template=typescript
npx create-react-app my-app-typescript --template=typescript
  • 우리가 앞에서 템플릿 옵션 없이 생성한 리액트 프로젝트에 타입스크립트를 적용한 것과 동일한 것을 볼 수 있음

절대 경로 설정

  • 리액트 프로젝트 개발 시 우리는 수많은 리액트 컴포넌트를 제작하고, 제작한 컴포넌트를 블록 조립하듯 하여 페이지를 제작함
  • 이 때 리액트 컴포넌트는 보통은 상대 경로 (import Button from ‘../../../Button’)을 사용하여 불러와 사용하게 됨
  • 컴포넌트 개수가 적고 폴더 구조가 복잡하지 않을 때는 큰 문제가 없지만 프로젝트 폴더 구조가 복잡해지면 파일 경로를 명확하게 파악하기 어렵다.
  • 이는 tsconfig.json 파일 수정을 통해 절대 경로를 설정하여 해결할 수 있다.
{
  "compilerOptions": {
    "target": "es5",
    "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",
    "baseUrl": "./src"  // 추가
  },
  "include": [
    "src"
  ]
}
  • src/component/Button.tsx 컴포넌트를 추가한다고 가정했을 때, 이제 아래와 같이 사용 가능하다.
    • 상대경로, 절대경로 두 가지 방법 모두 가능
// 상대경로
import Button from './component/Button.tsx'

// 절대경로
import Button from 'component/Button.tsx'

Prettier

  • Prettier는 코드 포맷터(Code Formatter)로 JavaScript, CSS, JSON 등을 지원
  • 미리 약속한 코드 스타일에 맞춰 자동으로 코드의 형식을 수정해주는 도구로, 협업시 여러 개발자들의 코드 스타일을 맞추는데 큰 도움을 줌

Prettier 설치

  • 리액트 프로젝트에서 다음 명령어를 사용하여 Prettier 라이브러리를 설치
npm install --save-dev prettier

Prettier 설정

  • React에서 Prettier를 사용하기 위해서는 사용할 코드 포맷을 미리 정의할 필요가 있음.
  • 코드 포맷을 미리 정의하기 위해 프로젝트 루트 경로에 .prettierrc.js 또는 .prettierrc.json파일을 생성하고 프로젝트 규칙에 맞게 수정
    • 더 많은 옵션을 확인하고 싶다면 공식문서 참고
  • .prettierrc.js 일 경우
module.exports = {
	tabWidth: 2,  // 들여쓰기 크기
  semi: true,  // 모드 마지막 줄에 세미콜론 사용할지에 대한 옵션
  singleQuote: true,  // 홑따옴표(')를 주로 사용하도록 설정
  trailingComma: 'all',  // 객체나 배열의 마지막 원소 끝에도 , 를 사용할지에 대한 옵션
};
  • .prettierrc.json일 경우
{
  "trailingComma": "all", 
  "semi": true, 
  "singleQuote": true,
	"tabWidth": 2 
}

Prettier 실행

  • 코드 포맷 검사하는 명령어
npx prettier --check ./src
  • 코드 포맷팅하는 명령어
npx prettier --write ./src
  • 명령어를 쉽게 사용하기 위해 package.json 파일에 스크립트 추가하기
    • format 스크립트는 Prettier를 check 옵션과 함께 실행하여 우리가 설정한 내용에 위반되는 내용이 있는지 검사
    • format:fix 스크립트는 Prettier를 write 옵션과 함께 사용하여 잘못된 내용을 설정한 내용에 맞게 자동으로 수정해줌
{
	...
  "scripts": {
    ...
    "eject": "react-scripts eject",
    "format": "prettier --check ./src",
    "format:fix": "prettier --write ./src" 
  },
  ...
}
  • 이제 다음과 같이 format 스크립트를 실행하여 잘못된 내용이 있는지 확인해보자.
npm run format
  • 명령어 실행히 완료되면, 다음과 같은 결과를 확인할 수 있음
    • src/index.tsx 파일에서 우리가 설정한 내용을 위반하고 있음을 알려주고 있다.

Checking formatting...
[warn] src/index.tsx
[warn] Code style issues found in the above file. Run Prettier to fix.
  • 위반 내용을 Prettier를 사용하여 수정하기 위해 다음 명령어를 실행한다.
npm run format:fix
  • 명령어가 실행되면, 다음과 같이 src 폴더 하위의 모든 파일들을 검사하고 수정하는 것을 확인할 수 있다.

src/App.css 18ms
src/App.test.tsx 98ms
src/App.tsx 5ms
src/index.css 2ms
src/index.tsx 5ms
src/react-app-env.d.ts 1ms
src/reportWebVitals.ts 4ms
src/setupTests.ts 1ms
  • Prettier가 실제로 문제를 잘 해결했는지 확인하기 위해 다음과 같이 format을 검사하는 명령어를 실행해보자.
npm run format
  • 명령어 실행이 완료되면, 다음과 같이 Prettier가 모든 문제를 잘 해결한 것을 볼 수 있다.

VSCode 설정

  • Prettier는 다양한 에디터에서 사용 가능
  • 그 중 VSCode에서 설정하는 방법에 대해 알아보자.
  • VSCode의 Prettier 플러그인 설치

  • 설치가 완료되었다면, VSCode를 열고 설정 페이지로 이동 후 settings.json 열기
    • (macOS) cmd + ,
    • (Windows) ctrl + ,

  • settings.json 파일 다음과 같이 수정
{
  ...
  "editor.formatOnSave": true,
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}
  • 또는 다음과 같이 간단하게 설정 가능
{
  ...
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}
  • 이제 VSCode에서 파일을 수정하고 저장하면, 자동으로 코드가 포맷팅되는 것을 확인할 수 있음.

ESLint

  • ECMAScript와 Lint(에러 코드 표식)의 합성어로, 자바스크립트의 코드를 분석하고 잠재적인 오류나 버그를 찾는데 도움을 주는 정적 분석 툴
  • 여러 개발자들이 하나의 소스코드를 수정하는 협업환경에서 ESLint는 소스 코드를 분석하고 오류나 버그의 가능성을 지적하거나 소스 코드의 스타일을 일관성 있게 관리해주기 때문에 Prettier와 함께 자주 사용됨.

VSCode ESLint 확장 프로그램 설치

ESLint 설치

  • 리액트 프로젝트에서 다음 명령어를 사용하여 ESLint 라이브러리를 설치
npm install eslint --save-dev

ESLint 설정

  • 설치가 완료되었다면 ESLint를 사용하기 위해 다음 명령어를 실행하여 ESLint 초기화
npx eslint --init
  • 명령어를 실행하면, 여러 옵션들을 선택하여 ESLint를 설정할 수 있음.
  1. ESLint를 설정하기 위해 필요한 라이브러리를 설치 여부
    • y를 눌러 필요한 라이브러리 설치

  1. 문제점을 찾는 것과 잘못된 점을 고치는 스크립트를 따로 작성할 예정이므로 To check syntax and find problems 선택

  1. ESLint를 사용하는 자바스크립트 프로젝트에서 모듈을 추가할 때에 어떤 방식을 사용하는지 선택하는 질문
    • 리액트는 기본적으로 자바스크립트 모듈(import/export) 방식을 사용하므로 JavaScript module (import/export) 옵션을 선택

  1. ESLint를 사용할 프레임워크를 선택하는 옵션으로 React 선택

  1. 타입스크립트 사용 여부에 Yes 선택

  1. 현재 프로젝트가 어떤 환경에서 실행되는지 선택
    • 리액트 프로젝트는 웹 브라우저에서 실행되므로 Browser 옵션 선택

  1. 지금까지 설정한 내용을 어떠한 형식으로 저장할지 물어보는 화면 표시
    • 원하는 파일 형식 선택
    • 아무거나 선택해도 상관 없으나 여기서는 JSON 옵션 선택

  1. 지금까지 설정한 내용을 적용하기 위해 추가적인 라이브러리를 설치할지 물어보는 화면이 표시됨
    • Yes 옵션을 선택후 패키지 매니저로 npm 옵션 선택 하여 해당 라이브러리 설치

  • 추가적으로 필요한 라이브러리를 설치한 후 .eslintrc.json 파일이 자동으로 생성되는 것을 확인할 수 있음.

설치 오류

  • @typescript-eslint/eslint-plugin@latest eslint-plugin-react@latest @typescript-eslint/parser@latest eslint@latest 패키지 설치 과정에서 오류가 발생하였음

  • @typescript-eslint/eslint-plugin@5.62.0@typescript-eslint/parser@6.6.0 간의 버전 충돌 때문
    • 패키지 버전을 명시적으로 지정하여 해결
    • 아래 코드를 package.json 에 추가한 후 npm install
"devDependencies": {
    "@typescript-eslint/eslint-plugin": "^5.62.0",
    "@typescript-eslint/parser": "^5.62.0",
    "eslint-plugin-react": "7.33.0"
 }

ESLint 룰

  • 위에서 생성된 .eslintrc.json파일을 확인해보면 다음과 같은 형태를 확인할 수 있음.
{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:react/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint",
        "react"
    ],
    "rules": {
    }
}
  • extends를 살펴보면, ESLint, 리액트와 타입스크립트의 추천 룰을 사용하는 것을 확인할 수 있음.
    • 만약 ESLint와 타입스크립트를 검사하는 룰을 변경하고 싶다면, rules 옵션에 필요한 내용을 추가하면 됨
    • 변경을 원한다면 ESLint타입스크립트 공식문서 참고

airbnb 코드 스타일 적용하기

  • 다음 명령어 실행 후 y 선택하여 필수 플러그인 설치
npx install-peerdeps --dev eslint-config-airbnb
  • 다음 명령어 실행하여 의존하고 있는 패키지 확인
npm info "eslint-config-airbnb@latest" peerDependencies

  • npm i -D 명령어 사용하여 모두 설치
npm i -D eslint-config-airbnb-typescript

npm i -D eslint-plugin-import
npm i -D eslint-plugin-jsx-a11y
npm i -D eslint-plugin-react
npm i -D eslint-plugin-react-hooks
  • eslint와 prettier 충돌 방지 설정
    • eslint-config-prettier: : prettier와 겹치는 formatting 규칙을 비활성화
    • eslint-plugin-prettier: : eslint에 prettier의 규칙을 추가하여 prettier에서 인식하는 코드상의 포맷 오류를 ESLint 오류로 출력
npm install eslint-plugin-prettier eslint-config-prettier --save-dev
  • .eslintrc.json 수정
    • document나 setTimeout 과 같은 node, es6에서 쓰이는 코드 ESLint 오류로 인식하지 않기 위해 env 옵션 수정
    • airbnb JS style 적용하고 prettier 규칙을 eslint 규칙에 추가하고 prettier와 충돌하는 eslint 규칙을 끄기 위해 extends 옵션 수정
      • 다른 config를 사용하더라도 prettier를 맨 마지막에 넣어야 모든 중복 규칙을 비활성화 시킬 수 있다.
    • ts파일에서 tsx문법을 사용했을 때 오류가 발생하는 문제 해결하기 위해 rules 옵션 수정
{
  "env": {
    "browser": true,
    "es2021": true,
    "es6": true,
    "node": true
  },
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "airbnb",
    "airbnb/hooks",
    "prettier",
    "plugin:prettier/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint", "react"],
  "rules": {
    "prettier/prettier": ["error", { "endOfLine": "auto" }],
    "react/jsx-filename-extension": [
      2,
      { "extensions": [".js", ".jsx", ".ts", ".tsx"] }
    ]
  }
}
  • VSCode settings.json 파일 수정
{
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.codeActionsOnSave": {   // 추가
      "source.fixAll.eslint": true   // 추가
    }
}
  • 설정한 ESLint 에 따라 오류가 발생함을 확인할 수 있음.

  • Error Lens 확장 프로그램 설치 시 오류가 나는 코드 옆에 오류 원인이 함께 출력됨

ESLint 실행

  • 이제 설정한 ESLint를 사용하여 잠재적인 오류나 버그를 찾기 위한 실행 스크립트를 만들어보자.
  • 실행 스크립트를 추가하기 위해 package.json 파일을 열고 다음과 같은 코드 추가
    • lint 명령어는 src 폴더를 ESLint로만 검사하도록 설정
    • lint:fix 명령어는 ESLint를 fix 옵션과 함께 사용하여 우리가 설정한 룰을 기반으로 자동 수정하도록 설정
{
  ...
  "scripts": {
    "eject": "react-scripts eject",
    "lint": "eslint src/**/*.{js,jsx,ts,tsx,json}",
    "lint:fix": "eslint --fix src/**/*.{js,jsx,ts,tsx,json}"
  },
  ...
}
  • 이제 설정한 명령어를 실행하여 ESLint로 소스코드를 검사해보자.
    • ESLint가 대상 파일을 분석하고 코드에서 발견한 오류 및 경고를 터미널에 출력
npm run lint

  • 아래 명령어 실행시 코드 스타일 문제 중에서 자동으로 수정할 수 있는 코드 수정하고 나머지는 터미널에 출력
    • 자동 수정은 권장하지 않음.
npm run lint:fix

References

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

2개의 댓글

comment-user-thumbnail
2023년 9월 6일

정말 유용한 정보네요 ! 언제나 다른 사람에게 도움이 되는 정보를 주셔서 감사해요 😊

1개의 답글