JS' 공부흔적

[ESLint] import 순서 자동 정렬하기 본문

ESLint

[ESLint] import 순서 자동 정렬하기

이준수 2023. 8. 14. 22:25

올 상반기에 인턴으로 근무하면서 사내 코드 컨벤션에 의거하여 import 순서에 대해서 처음으로 신경 써봤다. 그러나 일일이 수작업으로 진행했던지라 가끔씩 지켜지지 않을 때도 있었고, 이런 경우 코드 리뷰 과정에서 수정하곤 했다.

 

이 부분에서 불편함을 느꼈기에 이번 사이드 프로젝트에서는 import 순서를 자동으로 정렬해 주는 Lint 설정을 직접 적용해 보자고 마음먹었다.

 

우선 eslint-plugin-import라는 라이브러리를 설치해야 한다. 이를 설치함으로써 import/export 구문에 대한 Lint를 지원한다.

문서를 확인해 보니 .eslintrc 파일에 추가 설정을 하라고 한다.

extends:
  - eslint:recommended
  - plugin:import/recommended
  # alternatively, 'recommended' is the combination of these two rule sets:
  - plugin:import/errors
  - plugin:import/warnings

# or configure manually:
plugins:
  - import

나는 plugins에 import를 추가했다.

 

이제 rules에 import/order 규칙을 추가하면 되는데, 나는 아래와 같이 사용했다.

"import/order": [
  "error",
    {
      "groups": [
        "builtin",
        "external",
        "unknown",
        ["sibling", "parent"]
      ],
      "pathGroups": [
        {
          "pattern": "{react*,react*/*}",
          "group": "external",
          "position": "before"
        }
      ],
      "pathGroupsExcludedImportTypes": [],
      "alphabetize": {
        "order": "asc",
        "caseInsensitive": true
      },
      "newlines-between": "always"
    }
  ]

하나씩 살펴보자!


error

정해진 import rules에 어긋났을 때 어떻게 처리할 것인지를 정하는 옵션이다. off, warn, error 3가지가 있는데 나는 error로 처리하도록 했다.

설정하지 않았을 때 발생하는 Error


groups

import문의 그룹을 정한다. 각 그룹은 공백으로 구분된다. builtin은 기본적으로 내장되어 있는 fs, path 등의 모듈, external은 외부 라이브러리, sibling은 ./로 표현할 수 있는 같은 디렉토리 내의 모듈, parent는 ../로 표현할 수 있는 부모 디렉토리 내의 모듈, unknown은 그룹화할 수 없는 것들이다. 특히 sibling과 parent는 internal로 합쳐질 수 있으며, 이밖에도 index, object, type이 있다.

 

내 프로젝트 내에서는 unknown으로 분류될 만한 것이 절대 경로 import 이외에는 없다고 생각하여 상대 경로 import보다 위에 위치하도록 설정했다. 또한 sibling과 parent는 그룹으로 묶어서 공백으로 구분되지 않도록 설정했다.

"groups": [
  "builtin",
  "external",
  "unknown",
  ["sibling", "parent"]
]

pathGroups

import문의 패턴을 통해서 좀 더 세부적인 순서를 정할 수 있다.

{
    "pattern": "{react*,react*/*}",
    "group": "external",
    "position": "before"
}

react로 시작하는 경로의 경우 external보다 앞에 위치하도록, 즉 어떤 외부 라이브러리보다도 위에 위치하도록 설정했다.
그러나 이렇게 설정했을 때 아래의 결과가 나타났다.

// 내가 의도한 것
import React from "react";
import ReactDOM from "react-dom";
import { useDispatch } from "react-redux";

import PropTypes from "prop-types";
// 실제 적용 결과
import PropTypes from "prop-types";
import React from "react";
import ReactDOM from "react-dom";
import { useDispatch } from "react-redux";

이처럼 pathGroups에서 정한 규칙이 적용되지 않는 것을 확인했고, 이를 이해하는 데에 상당히 오래 걸렸다. 이 에러의 해결법은 pathGroupsExcludedImportTypes 옵션을 사용하는 것이다.


pathGroupsExcludedImportTypes

pathGroups를 통해 설정한 규칙이 적용되지 않을 import type을 설정하는 옵션이다. 이 옵션의 기본값은 ["builtin", "external", "object"]이다. 즉, 이 옵션을 명시하지 않았을 때는 기본적으로 pathGroups에서 정한 규칙이 builtin, external, object에 적용되지 않는다는 뜻이다.

 

나는 pathGroups에서 react로 시작하는 경로가 external보다 앞에 위치하도록 설정했다. 그러나 external은 이 규칙이 적용되지 않기 때문에 위의 코드처럼 react로 시작하는 경로들도 똑같이 external 취급을 받는다.

 

따라서 이를 해결하기 위해서는 pathGroupsExcludedImportTypes 옵션에서 external을 제거해야 한다. 지금 상황에선 pathGroups 규칙이 하나밖에 없기 때문에 그냥 빈 배열로 설정했다.

"pathGroupsExcludedImportTypes": []

alphabetize

같은 그룹 내에서 알파벳 순서에 의한 정렬을 설정하는 옵션이다.

"alphabetize": {
  "order": "asc",
  "caseInsensitive": true
},

위처럼 설정하면 오름차순 정렬 및 대소문자 구분을 하지 않는다는 뜻이다.


newlines-between

그룹 사이에 공백 여부를 설정하는 옵션이다. always로 설정하면 항상 공백을 넣는다는 뜻이다.

"newlines-between": "always"

 

더 자세한 설정을 알고 싶다면 문서를 참고하길 바란다.


Lint 적용하기

package.json 파일에 아래와 같이 설정했다.

"scripts": {
  "lint": "eslint 'src/**/*.{js,jsx}'",
  "lint:fix": "eslint 'src/**/*.{js,jsx}' --fix",
},
# lint 검사만 진행
npm run lint

# lint 검사 후 자동 수정
npm run lint:fix

 

728x90
반응형