대범하게

ESLint, Prettier 무엇인지 알고 설정해보기 본문

Development/React

ESLint, Prettier 무엇인지 알고 설정해보기

대범하게 2024. 6. 3. 21:29
반응형

들어가면서

ESLint와 Prettier는 React의 기능이 아니지만, React 프로젝트에서 자주 사용하는 도구이기 때문에 해당 카테고리에 기술한다. 

 

Prettier와 Lint를 사용하지 않으면 다음과 같은 문제가 발생할 수 있다. 

 

- 의도하지 않은 구현 실수 때문에 에러가 발생하는 경우

(예를 들어, 일관되지 않게 function과 arrow function를 혼용하여 this 바인딩이 의도한대로 발생하지 않는 문제)

 

- 협업하는 인원이 많아질수록 개개인별 코드짜는 스타일이 달라 가독성이 떨어지는 경우

(예를 들어, 줄바꿈이 4줄코드와 2줄인 코드의 연속적인 충돌 혹은 사용하지 않는 인자들의 잔재)

 

이러한 문제들은 작지만 신경 쓰이는 부분들로, 개발 생산성을 저하시킬 수 있다. (사실 필자가 겪은 문제였다..)

 

따라서 ESLint와 Prettier를 설정해두어 이러한 문제들을 예방하는 것이 좋다.

 

ESLint와 Prettier 설정하기

(아래 기술한 내용은 React + Typescript에서 사용된 ESLint와 Prettier 설정이다. JS를 사용한다면 TS 관련 설정은 빼야한다.)

 

ESLint

목적: 코드의 오류(문제점)를 찾고 수정하기 위해.

역할: JS 코드를 검사해서 잘못된 부분이나 개선할 부분을 알려준다.

예를 들어, 변수 이름을 잘못 썼거나, 사용하지 않는 변수가 있으면 경고한다.

 

이처럼 isDark 변수를 선언해두고 한 번도 사용하지 않아 경고 해주고 있다.

 

개발자들이 놓칠 수 있는 코드 상의 문제를 검사하여 알려준다. 

 

Prettier

목적: 코드의 형식을 일관되게 하기 위해.

역할: 코드의 들여쓰기, 괄호, 줄바꿈 등 자동으로 정리해서 보기 좋은 코드를 만든다.

예를 들어, 들여쓰기를 2줄로 했다고 하더라도 4줄로 들여써지도록 자동으로 세팅된다. (prettier에 "tabWidth": 4 로 세팅했다는 가정하에)

 

개발자들이 코드 스타일에 신경 쓰지 않고도 일관된 코드 형식을 유지할 수 있게 도와준다.

 

프로젝트를 생성하였다면, 이제 ESLint와 Prettier를 설정해보자.

npm add --D eslint prettier eslint-config-prettier

 

eslintprettier, eslint-config-prettier를 추가한다. (해당 명령어를 실행하면 package.json 파일에서 추가된 것을 확인할 수 있다.)

 

eslint에도 포매팅 기능이 포함되어 있어 eslint와 prettier를 같이 사용하는 경우 충돌이 날 수 있다.

eslint-config-prettier(충돌하는 eslint 규칙을 전부 꺼주는 방법)는 ESLint와 Prettier를 함께 사용할 때 충돌하는 규칙들을 비활성화하여 충돌 없이 함께 동작할 수 있게 해주는 설정이다.

.eslintrc.cjs

프로젝트 root에 .eslintrc.cjs 파일을 생성한다. 

touch .eslintrc.cjs (명령어를 입력하여 파일을 생성하거나, vscode 내에서 해당 이름의 파일을 만든다.)

아래 코드를 추가.

module.exports = {
    root: true,
    env: { browser: true, es2020: true },
    extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended'],
    // dist 디렉토리와 .eslintrc.cjs 파일을 ESLint 검사에서 제외
    ignorePatterns: ['dist', '.eslintrc.cjs'],
    parser: '@typescript-eslint/parser',
    plugins: ['react-refresh', 'import', 'prefer-arrow'],
    rules: {
        // React 컴포넌트만 export하도록 경고
        'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
        // 타입 임포트를 일관되게 사용하도록 강제
        '@typescript-eslint/consistent-type-imports': 'error',
        // 함수 반환 타입을 명시하도록 강제
        '@typescript-eslint/explicit-function-return-type': 'error',
        // 네이밍의 일관성을 위한 규칙을 설정
        '@typescript-eslint/naming-convention': [
            'error',
            {
                selector: [
                    'variableLike',
                    'classProperty',
                    'objectLiteralProperty',
                    'typeProperty',
                    'classMethod',
                    'objectLiteralMethod',
                    'typeMethod',
                    'accessor',
                ],
                format: ['camelCase'],
                leadingUnderscore: 'allow',
            },
            {
                selector: ['variable'],
                types: ['function'],
                format: ['camelCase', 'PascalCase'],
                leadingUnderscore: 'allow',
            },
            { selector: ['variable'], modifiers: ['global'], format: ['camelCase', 'PascalCase', 'UPPER_CASE'] },
            {
                selector: [
                    'classProperty',
                    'objectLiteralProperty',
                    'typeProperty',
                    'classMethod',
                    'objectLiteralMethod',
                    'typeMethod',
                    'accessor',
                    'enumMember',
                ],
                format: null,
                modifiers: ['requiresQuotes'],
            },
        ]
    },
};

 

.prettierc.json

{
// 줄 바꿈을 수행할 줄의 최대 길이를 설정 (120)
    "printWidth": 120,
    // 탭을 공백으로 변환할 때 사용할 공백의 수를 설정 (4)
    "tabWidth": 4,
    // 탭 대신 공백을 사용할지 여부를 설정 (false)
    "useTabs": false,
    // 명령문의 끝에 세미콜론을 추가할지 여부를 설정 (true)
    "semi": true,
    // 문자열에 작은 따옴표를 사용할지 여부를 설정 (true)
    "singleQuote": true
}

 

규칙이 타이트하거나, 자신에게 편한 방법이 있다면 직접 세부 룰을 찾아보고 수정하는 것을 권한다.

 

마치며 

약간의 회고를 더하면, 사내에서 모노레포로 전환하는 프로젝트를 진행하게 되면서 고대하던(?) ESLint와 Prettier를 적용할 수 있게 되었다. 기존 메인 레포에 ESLint와 Prettier를 적용하게 되면, 해당 설정들을 벗어나는 많은.. 양의 코드를 수정해야했기 때문에 쉽사리 진행하기 쉽지 않았다. ESLint와 Prettier를 처음 접했을 때는 엄격하다고 생각했는데 적응을 하니 코드들의 패턴이 보이고, 불필요한 코드들이 사라졌다는 점에서 굉장히 만족한다.

 

추가적으로 설정하고 싶은 규칙은 다른 프로젝트를 참고하거나 문서를 통해 확인해볼 수 있다.

(오픈소스에서 사용되어있는 ESLint, Prettier 세팅을 보거나, plugin을 찾아보는게 도움이 되었다. 그리고 필요한 규칙을 만들 수도 있다...!) 프로젝트에서 코드의 일관성과 품질을 높이는데 큰 일조를 하는 두 친구에서 영광(?)을 바치며 마무리한다. 

 

- ESLint 규칙 문서: https://eslint.org/docs/latest/rules/

- TypeScript ESLint 규칙 문서: https://typescript-eslint.io/rules/

 

 

Comments