CRA React+Typescript+ Eslint(airbnb)+Prettier 초기설정

신세원·2021년 9월 22일
2

React

목록 보기
6/28

React와 Typescript 그리고 Eslist까지 접목해서 초기설정하는 부분들은 자료마다 다들 달라서, 한 3일동안 애를 먹었다.
부디 지금 정리하는 자료들이 나처럼 삽질하는 사람들에게 큰 보탬이 됐으면 하는 바람이다.

  • create-react-app typescript 설치
  • eslint(airbnb) & prettier 설치

이 블로그에서는 자세한 설명보다는 순서대로 복붙하며 설정하는 부분에 더 많은 포커스를 두었다.

총 설치 목록
npm i -D eslint eslint-config-airbnb eslint-plugin-prettier eslint-config-prettier prettier

1. 파일 생성

$npx create-react-app '프로젝트명' -—template typescript

위와 같이 파일을 생성하면 루트에 tsconfig.json 파일이 생기는데, default 상태에서 "baseUrl" : "./src" 코드를 추가해준다.
이 뜻은 ./src를 절대 경로로 갖겠다는 의미이다. tsconfig.json 수정본은 아래와 같다.

//tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "baseUrl": "./src", //이 부분 추가
    "allowJs": true,
    "noImplicitAny": true, //이 부분도 추가, 모든 타입의 any라도 넣으라는 뜻이다.
    "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"]
}

2. Eslint 설치

ESLint는 코드의 가독성을 높여주는 extension이다. 코드를 분석해 문법적인 오류나 안티 패턴을 찾아주고 일관된 코드 스타일로 작성하도록 돕는다.
ESLint는 스타일 가이드를 좀 더 편리하게 적용하기 위해 사용하기도 하는데, 외부에 공개되어 많은 개발자가 사용 중인 Airbnb Style Guide, Google Style Guide가 대표적이다.
Prettier는 개발자가 작성한 코드를 정해진 코딩 스타일을 따르도록 변환해주는 자바스크립트 라이브러리이다.

2-1 ) 프로젝트에서 eslint 설치

$npm install -D eslint (위에 총 설치목록에서 이미 설치했다면 패스)

2-2 ) 프로젝트 루트 폴더에서 "npx eslint --init" 입력

$npx eslint --init

npx eslint init을 하게도면 여러 옵션을 선택하는 창이 나오는데 자신의 프로젝트에 맞게 하면 되는데, 필자처럼 하면 무난하다.

  1. How would you like to use ESLint?
  • To check syntax, find problems, and enforce code style
  1. What type of modules does your project use?
  • JavaScript modules (import/export)
  1. Which framework does your project use?
  • React
  1. Does your project use TypeScript?
  • Yes
  1. Where does your code run?
  1. What format do you want your config file to be in?
  • Javascript
  1. Would you like to install them now with npm?
  • Yes

3) 추가 플러그인 설치

$npm i -D eslint-config-airbnb # 리액트 관련 규칙 O -> 우리는 이걸 사용. 왜? 리액트를 사용할거니까!
$npm i -D eslint-config-airbnb-base # 리액트 관련 규칙 X

위에 있는걸 설치하면 자동으로 devDependencies에 아래 항목들이 추가된다.

  • eslint-plugin-import : ES6의 import, export 구문을 지원, 필수 플러그인
  • eslint-plugin-react : React 규칙이 들어있는 플러그인
  • eslint-plugin-react-hooks : React Hooks 규칙이 들어있는 플러그인
  • eslint-plugin-jsx-a11y : JSX요소의 접근성 규칙에 대한 정적 검사 플러그인

그리고 airbnb에서 제작한 리액트 관련 규칙을 설정해주는 플러그인을 설치한다.

$npm i -D eslint-plugin-prettier eslint-config-prettier

4).eslintrc.js 파일 생성 및 수정

npx eslint init 질문이 끝나고 새로고침하면 프로젝트 루트 안에 .eslintrc.js 파일이 생성이 될 것이다.

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: ['eslint:recommended', 'plugin:prettier/recommended', 'airbnb'],
  parserOptions: {
    ecmaFeatures: { jsx: true },
    ecmaVersion: 2021,
    sourceType: 'module',
  },
  plugins: ['react'],
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        moduleDirectory: ['node_modules', 'src/'], // 절대경로 노드 설정
      },
    },
  },
  parser: '@babel/eslint-parser',

  rules: {
    'import/extensions': [ 
      'error',
      'ignorePackages',
      { js: 'never', jsx: 'never', ts: 'never', tsx: 'never', json: 'never' },
    ],
    'react/no-unstable-nested-components': 'off', // 컴포넌트 분리
    camelcase: 'off',
    'react/function-component-definition': 'off',
    'no-use-before-define': 'off',
    'no-shadow': 'off',
    'no-useless-escape': 'off',
    'prettier/prettier': [
      'error',
      {
        trailingComma: 'all',
        tabWidth: 2,
        semi: true,
        printWidth: 80,
        singleQuote: true,
        useTabs: false,
      },
    ],
    // include: ['src'],
    // exclude: ['node_modules/**', 'build/**', 'coverage/**'],

    'react/jsx-props-no-spreading': 'off',
    'react/jsx-curly-newline': 'off',
    'no-console': 'off',
    indent: 'off', // tab 공백 에러,
    'implicit-arrow-linebreak': 0,
    'import/no-unresolved': [2, { caseSensitive: false }], // import 절대경 지정 문제('https://xxxxersuy.com/19'),
    'operator-linebreak': 0,
    'react/prop-types': ['off'], // https://forhjy.medium.com/react-solution-for-children-is-missing-in-props-validation-eslint-react-prop-types-2e11bc6043c7,
    'object-curly-newline': 0, // https://runebook.dev/ko/docs/eslint/rules/object-curly-newline,
    'jsx-a11y/no-static-element-interactions': [
      'error',
      {
        handlers: [
          'onClick',
          'onMouseDown',
          'onMouseUp',
          'onKeyPress',
          'onKeyDown',
          'onKeyUp',
        ],
      },
    ],
    'react/jsx-curly-brace-presence': 0,
    'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
    'import/prefer-default-export': 'off',
    'no-confusing-arrow': 0,
    'no-underscore-dangle': 0,
    'spaced-comment': 0,
    'no-param-reassign': 0,
    'import/no-cycle': 'off',
    'function-paren-newline': 'off',
    'jsx-a11y/media-has-caption': [
      2,
      {
        audio: ['Audio'],
        video: ['Video'],
        track: ['Track'],
      },
    ],
    'no-unused-vars': 'off',
    'react/jsx-one-expression-per-line': 'off',
    'react/jsx-wrap-multilines': [
      'error',
      { declaration: false, assignment: false, return: true },
    ],
  },
};





// 조금 더 간단하게

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    'airbnb',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:prettier/recommended',
  ],
  parserOptions: {
    ecmaFeatures: { jsx: true },
    ecmaVersion: 2021,
    sourceType: 'module',
  },
  plugins: ['react'],
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        moduleDirectory: ['node_modules', 'src/'], // 절대경로 노드 설정
      },
    },
  },
  parser: '@babel/eslint-parser',

  rules: {
    'linebreak-style': 0,
    'import/prefer-default-export': 0,
    'prettier/prettier': 0,
    'import/extensions': 0,
    'no-use-before-define': 0,
    'import/no-unresolved': 0,
    'import/no-extraneous-dependencies': 0, // 테스트 또는 개발환경을 구성하는 파일에서는 devDependency 사용을 허용
    'no-shadow': 0,
    'react/prop-types': 0,
    'react/jsx-filename-extension': [
      2,
      { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
    ],
    'jsx-a11y/no-noninteractive-element-interactions': 0,
  },
};



그리고 해당 파일 안에 내용을 아래와 같이 채워주면 된다.
extends는 ESLint에 적용할 규칙들을 정의해주는 곳이다
나중에 정의된(= 밑에 있는) 옵션일수록 높은 우선순위를 가진다.
그리고 eslint는 엄청나게 엄격한 규칙을 요구하는데, 가끔 그러한 규칙을 무시하고 싶을 때가 있다.
그러면 rules 란에 '해당 규칙' : 0의 옵션을 주면 그 규칙을 무시하겠다 라는 뜻이 된다.
자신의 입맛에 맞게 설정하면 되겠다.

5. prettier 설치

ESLint는 문법 에러를 잡아내고, 코드 품질을 검사하기 위해 사용하고, Prettier는 '한 줄의 최대 길이', 'tab'을 쓸 것인지 'space'를 쓸 것인지, 문자열을 '(홑 따옴표)로 할 것인지 "(큰따옴표)로 할 것인지 같이 정해진 코딩 스타일에 맞게 코드를 변환하기 위해 사용한다.
따라서 Prettier와 ESLint를 같이 쓰면 코드 품질을 바로 잡은 뒤 코드를 정해진 코딩 스타일에 맞게 바꿀 수 있다.

5-1 ) 프로젝트에서 prettier 설치

$npm install -D prettier

5-2 ) 프로젝트 루트 폴더에 .prettierrc 파일 생성 및 코드 수정

프로젝트 루트 폴더에 .prettierrc 파일을 생성한다.
저기 폴더 안에는 formatting에 대한 규칙을 적어주는 곳이다.

{
  "singleQuote": true, 
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "arrowParens": "always",
  "orderedImports": true,
  "bracketSpacing": true,
  "jsxBracketSameLine": false
}

여기까지 다 했으면 끝!!

마지막으로 절대경로까지 설정해주면 금상첨화인데 절대경로 설정하는 내용은 아래 자료 참고바란다!

React Typescript | 절대경로 적용하기(feat.React-CRA)

<참고자료>
Cannot use JSX unless the '--jsx' flag is provided.ts(17004) 대처법
[React] create-react-app & Typescript 초기 세팅 완벽 정리

profile
생각하는대로 살지 않으면, 사는대로 생각하게 된다.

0개의 댓글