지금까지 나는 무지성으로 ESLint를 사용해 온 것인가... 라는 생각이 들었다.
처음 프론트엔드 개발을 시작했을 때, 내가 알고 지내던 풀스택 개발자 친구에게서 ESLint와 Prettier를 꼭 설정하라는 조언을 들었다. 하지만 그때 당시 웹 개발에 무지했던 나로서는 그게 도대체 뭔지 알 길이 없었고, 그 후 지금까지도 이것들에 대한 필요성을 크게 느끼지 못했다.
하지만 최근 협업 기회가 생겨 다른 개발자 분과 프로젝트를 진행 하려던 중, 그분깨서 husky 사용에 대한 여부를 물으셨다. 당연히 나는 그게 뭐죠? 를 시전했고, 이를 개인적으로 공부해본 결과 ESLint와 밀접한 연관이 있음을 알게 되었다.
따라서 오늘부터 개인적인 시간을 내어 이것들이 대체 뭐고, 어떻게 쓰는 것인지를 공부하고자 한다.
Lint란?
ESLint는 크게 5가지 과정을 거쳐 동작한다.
const a = 1 + "foo"
{
"type": "Program",
"start": 0,
"end": 19,
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 19,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 19,
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"name": "b"
},
"init": {
"type": "BinaryExpression",
"start": 10,
"end": 19,
"left": {
"type": "Identifier",
"start": 10,
"end": 11,
"name": "a"
},
"operator": "+",
"right": {
"type": "CallExpression",
"start": 14,
"end": 19,
"callee": {
"type": "Identifier",
"start": 14,
"end": 17,
"name": "foo"
},
"arguments": [],
"optional": false
}
}
}
],
"kind": "const"
}
],
"sourceType": "module"
}
이를 트리 구조로 도식화하면 아래와 같은 이미지가 나오게 된다.
이후 parser를 통해 각 노드를 순회하면서, 해당 노드의 Type과 동일한 이름의 이벤트를 발생시킨다.
발생된 이벤트는 Rules의 리스너에게 전달되고, 해당 노드가 규칙을 지키고 있는지를 검사한다.
brower
의 경우 window, node
의 경우 global 등..recommand
, all
, strict
config option 을 적용할 수 있음.eslint-plugin-
접두사를 가진 패키지의 경우, 이를 제거하고 plugin:/
을 붙여 추가.eslint-config-
접두사를 가진 패키지의 경우, 이를 제거한 나머지를 적용시키면 됨.{
"extends": [
"airbnb-typescript", // eslint-config-airbnb-typescript 패키지 사용.
"plugin:react/recommended", // eslint-plugin-react 패키지의 recommand 옵션 사용.
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@next/next/recommanded" // @next/eslint-plugin-next 패키지의 recommand 옵션 사용.
]
}
true
로 설정된 설정 파일을 만났다면, 더 이상 상위 폴더로 올라가지 않음.babel-parser
가, Typescript의 경우 @typescript-eslint/parser
가 쓰인다.recommended
설정에 포함되는 경우가 많다.4-1. parserOption : ESLint 사용을 위해 지원하려는 JS 옵션을 지정할 수 있음.
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 11,
}
}
// 이렇게 plugins만 설정하면 해당 extension이 작동하지 않는다.
{
"plugins": ["import", "react"]
}
{
"extends": ["airbnb"],
"rules": {
"no-console": "error",
"import/prefer-default-export": "off"
}
}
{
"settings": {
"react": {
"version": "detect"
}
}
}
node_module
폴더나 .
으로 시작하는 설정 파일을 기본적으로 무시함.--ignore-path
를 사용하면 됨.eslint --ignore-path .gitignore
{
"plugins": ["react"],
"rules": {
"react/jsx-uses-react": "error",
"react/jsx-uses-vars": "error"
}
}
recommand
나 all
, strict
같은 자체적인 config를 지원한다.{
"extends": ["plugin:react/recommended"]
}
all
, recommand
옵션에 대한 plugin과 rules 목록을 사전에 적용하였다.module.exports = {
deprecatedRules,
rules: allRules,
configs: {
recommended: Object.assign({}, configRecommended, {
plugins: eslintrcPlugins,
}),
all: Object.assign({}, configAll, {
plugins: eslintrcPlugins,
rules: activeRulesConfig,
}),
'jsx-runtime': Object.assign({}, configRuntime, {
plugins: eslintrcPlugins,
}),
},
};
eslint-config-prettier
패키지의 경우, Prettier와 충돌 가능성이 있는 옵션을 전부 Off 해준다.