ESLint
ESLint는 JavaScript 코드에서 발견 된 문제 패턴을 식별하기위한 정적 코드 분석 도구입니다. ESLint의 규칙은 구성 가능하며 사용자 정의 된 규칙을 정의하고로드 할 수 있습니다. ESLint는 코드 품질과 코딩 스타일 문제를 모두 다룹니다.
Categories
Plugins
- typescript-eslint
- @typescript-eslint/typescript-estree - TypeScript 코드용 ESTree 호환 AST를 생성하는 파서입니다.
- @typescript-eslint/eslint-plugin - Typescript 관련 린팅규칙을 설정하는 플러그인
- @typescript-eslint/parser - Typescript 를 파싱하기 위해 사용
- eslint-config-airbnb - airbnb 코딩규칙을 사용(리액트 코딩규칙 포함)
- eslint-config-prettier - prettier와 충돌을 일으키는 ESLint 규칙들을 비활성화 시키는 config
- eslint-plugin-prettier - Prettier에서 인식하는 코드상의 포맷 오류를 ESLint 오류로 출력
- eslint-plugin-react - React에 관한 린트설정을 지원
- eslint-plugin-react-hooks - React Hooks의 규칙을 강제하도록 하는 플러그인
- eslint-plugin-jsx-a11y - JSX 내의 접근성 문제에 대해 즉각적인 AST 린팅 피드백을 제공
- eslint-plugin-import - ES2015+의 import/export 구문을 지원하도록 함
- eslint-import-resolver-typescript - Typescript import 순서 자동 정렬
- eslint-import-resolver-webpack - Webpack 모듈. "동기식 (synchronous)" 설정만 적용 가능.
React
- eslint-config-react-app
- @typescript-eslint/parser
- @typescript-eslint
- @babel/eslint-parser
E.T.C
Command Line Interface
Fix problems
-
--fix
- Automatically fix problems -
--fix-dry-run
- Automatically fix problems without saving the changes to the file system -
--fix-type Array
- Specify the types of fixes to apply (directive, problem, suggestion, layout)
Configuration File Formats
ESLint는 여러 형식의 구성 파일을 지원합니다.
- JavaScript - use
.eslintrc.js
and export an object containing your configuration. - JavaScript (ESM) - use
.eslintrc.cjs
when running ESLint in JavaScript packages that specify"type":"module"
in theirpackage.json
. Note that ESLint does not support ESM configuration at this time. - YAML - use
.eslintrc.yaml
or.eslintrc.yml
to define the configuration structure. - JSON - use
.eslintrc.json
to define the configuration structure. ESLint's JSON files also allow JavaScript-style comments. - Deprecated - use
.eslintrc
, which can be either JSON or YAML. - package.json - create an
eslintConfig
property in yourpackage.json
file and define your configuration there.
동일한 디렉토리에 여러 구성 파일이있는 경우 ESLint는 하나만 사용합니다. 우선 순위는 다음과 같습니다.
-
.eslintrc.js
-
.eslintrc.cjs
-
.eslintrc.yaml
-
.eslintrc.yml
-
.eslintrc.json
-
.eslintrc
-
package.json
다음 명령으로 손쉽게 설정파일을 만들 수 있다:
$ yarn create @eslint/config
yarn create v1.22.10
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "@eslint/create-config@0.1.2" with binaries:
- create-config
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ How would you like to define a style for your project? · prompt
✔ What format do you want your config file to be in? · JSON
✔ What style of indentation do you use? · 4
✔ What quotes do you use for strings? · single
✔ What line endings do you use? · unix
✔ Do you require semicolons? · No / Yes
The config that you've selected requires the following dependencies:
@typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
✔ Would you like to install them now with npm? · No / Yes
Installing @typescript-eslint/eslint-plugin@latest, @typescript-eslint/parser@latest
npm WARN rm not removing /home/your/Project/answer-dev/api/node_modules/.bin/semver as it wasn't installed by /home/your/Project/answer-dev/api/node_modules/semver
npm notice created a lockfile as package-lock.json. You should commit this file.
+ @typescript-eslint/parser@5.18.0
+ @typescript-eslint/eslint-plugin@5.18.0
added 1 package from 1 contributor, removed 1 package, updated 373 packages and audited 387 packages in 13.706s
50 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Successfully created .eslintrc.json file in /home/your/Project/answer-dev/api
Done in 35.86s.
Options
root
ESLint를 설정할 때는 여러 개의 설정 파일을 사용할 수 있는데요. 특히 Monorepo와 같이 하나의 코드 저장소(repository)에서 여러 개의 프로젝트가 공존하는 경우 매우 유용합니다.
ESLint는 현재 린트(lint) 대상의 파일이 위치한 폴더 안에 설정 파일이 있는지 우선적으로 확인해보고 없으면 그 상위 폴더를 한 단계 씩 거슬러 올라가면서 설정 파일을 찾게되는데요. root 옵션이 true로 설정되어 있는 설정 파일을 만나면 더 이상 상위 폴더로 올라가지 않습니다.
예를 들어, 프로젝트의 별 설정 파일에는 root 옵션을 false로 설정하고, 코드 저장소 최상위 경로에는 root 옵션을 true로 설정하면 코드 저장소의 공통 설정과 프로젝트 별 특화 설정을 분리해서 관리할 수 있어서 편리합니다.
env
자바스크립트는 다양한 환경에서 실행될 수 있는데 각 환경마다 전역(global) 변수를 통해 접근이 가능한 고유한 객체들이 있습니다. 대표적인 예로, 브라우저 환경에서는 전역에서 접근이 가능하지만 NodeJS 환경에서는 불가능한 window 객체를 들 수가 있겠네요.
ESLint는 기본적으로 미리 선언하지 않고 접근하는 변수에 대해서는 오류를 내기 때문에 이렇게 각 실행 환경(runtime)에서 기본적으로 제공되는 전역 객체에 대해서 설정을 통해 알려줘야 하는데요. 이러한 역할을 실행 파일의 env 옵션이 담당합니다.
예를 들어, ESLint로 린트(lint)를 할 자바스크립트 코드가 브라우저에서 실행될 수도 있고, NodeJS에서도 실행될 수 있다면, 두 가지 실행 환경에서 접근 가능한 모든 전역 객체를 다음과 같이 등록해줄 수 있습니다.
plugins
ESLint에는 기본으로 제공되는 규칙(rule) 외에도 추가적인 규칙(rule)을 사용할 수 있도록 만들어주는 다양한 플러그인(plugin)이 있는데요. 아마도 ESLint가 자바스크립트 커뮤니티에서 가장 많이 사용되는 린터(linter)가 된 이유는 바로 이 강력한 플러그인(plugin) 생태계라고 해도 과언이 아닐 것입니다.
플러그인은 설정 파일의 plugins 옵션을 통해서 설정하는데요. 예를 들어, 불러오기(import)와 React와 관련된 규칙은 다음과 같이 추가할 수 있습니다.
당연히 먼저 프로젝트에 해당 플러그인을 개발 의존성으로 설치해놨어야 되겠죠? 보통 ESLint 플러그인의 npm 패키지 이름은 eslint-plugin-
로 시작하오니 참고바랍니다.
플러그인을 설정할 때 흔히 오해하게 되는 부분이 단순히 플러그인만 추가해주면 관련 규칙이 바로 활성화된다고 생각하는 것인데요. 사실 플러그인은 새로운 규칙을 단순히 설정이 가능한 상태로 만들어주기만 합니다. 규칙을 위반하면 오류(error)를 낼지 경고(warn)를 낼지 아니면 해당 규칙을 끌지(off)에 대해서는 다음에 설명드릴 #extends 옵션이나 #rules 옵션을 통해서 추가 설정을 해줘야 합니다.
extends
Google, Facebook, Airbnb 등 수많은 세계적인 기업들이 ESLint로 자바스크립트 코드를 린트(lint)하는데요. 설정 파일의 extends 옵션을 통해서 이러한 기업들이 공개해놓은 설정을 그대로 가져와 기반(base) 설정으로 활용할 수 있습니다.
예를 들어, Airbnb에서 npm 저장소에 공개한 ESLint 설정인 eslint-config-airbnb를 기반 설정으로 사용해볼까요?
이렇게 확장이 가능한 ESLint 설정은 npm 패키지 이름이 eslint-config-
로 시작하며 extends
옵션에 명시할 때는 위와 같이 앞 부분을 생략해도 무방합니다.
뿐만 아니라 대부분의 ESLint 플러그인은 추천 설정을 제공하는데요. extends
옵션은 이러한 추천 설정을 사용할 때도 사용됩니다.
예를 들어, 위에서 설정한 import와 react 플러그인에서 제공하는 추천 설정을 사용해볼까요?
{
"plugins": ["import", "react"],
"extends": ["plugin:import/recommended", "plugin:react/recommended"]
}
rules
설정 파일에서 rules 옵션은 규칙 하나 하나를 세세하게 제어하기 위해서 사용되는데요. 일반적으로는 extends 옵션을 통해서 설정된 규칙을 덮어쓰고 싶을 때 유용하게 쓸 수 있습니다.
예를 들어, Airbnb 기반 설정에서는 no-console
규칙을 어기면 경고(warn)를 내고, import/prefer-default-export
규칙을 어기면 오류(error)를 내도록 되어 있는데요. 만약에 no-console
규칙을 어겼을 시, 경고 대신에 오류를 내고, import/prefer-default-export
규칙은 비활성화해 보겠습니다.
{
"extends": ["airbnb"],
"rules": {
"no-console": "error",
"import/prefer-default-export": "off"
}
}
이렇게 ESLint는 rules
옵션으로 명시된 규칙을 extends
옵션을 통해서 가져온 규칙보다 우선 시 해주는데요. rules
옵션을 많이 사용하면 사용할 수록 직접 관리해야하는 설정이 늘어나는 부작용이 있으니 주의가 필요합니다.
아무래도 위에서 배운 extends
옵션을 통해 자바스크립트 커뮤니티에서 유지보수가 잘 되고 있는 공개된 설정을 적극적으로 활용하는 것이 유지보수 측면에서 유리하겠죠?
parser, parserOptions
개발자가 작성하는 자바스크립트 코드는 실제로 브라우저와 같은 실행 환경에서 실제로 돌아가는 코드와 다른 경우가 많은데요. 대표적인 예로 타입스크립트나 JSX와 같은 자바스크립트의 확장 문법으로 개발하거나 Babel과 같은 트랜스파일러 (Transpiler)를 통해 최신 문법으로 개발하는 경우를 들 수 있습니다.
개발자들이 항상 최신 문법의 자바스크립트로 코딩할 수 있도록 도와주는 도구인
Babel에
대한 자세한 내용은 관련 태그를 참고 바랍니다.
ESLint는 기본적으로 순수한 자바스크립트 코드만 이해할 수 있기 때문에 자바스크립트의 확장 문법이나 최신 문법으로 작성한 코드를 린트(lint)하기 위해서는 그에 상응하는 파서(parser)를 사용하도록 설정해줘야 합니다.
예를 들어, 타입스크립트와 JSX를 사용하여 작성된 코드를 린트(lint)하도록 설정해보겠습니다.
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 11,
}
}
이번에는 Babel파서로 사용하도록 설정해보겠습니다.
물론 해당 파서를 사용하기 위해선 관련 패키지를 설치해야 한다.
settings
일부 ESLint 플러그인은 추가적인 설정이 가능한데요. 이런 경우에는 설정 파일의 settings 옵션을 사용합니다.
예를 들어, react 플러그인이 프로젝트에 설치된 리액트의 버전을 자동으로 탐지하도록 설정해보겠습니다. (기본 설정은 리액트 최신 버전을 기준으로 린트(lint)를 하게 되었습니다.)
다른 플러그인에 대한 구체적인 설정 방법은 해당 플러그인의 공식 문서를 참고바라겠습니다.
ignorePatterns
ESLint는 린트(lint)를 수행할 때 기본적으로 node_modules
폴더나 .
로 시작하는 설정 파일은 무시하는데요. 그 밖에 다른 파일을 무시하고 싶다면 설정 파일의 ignorePatterns 옵션을 사용할 수 있습니다.
이 방법 대신에 .gitignore
파일과 유사한 방식으로 .eslintignore
파일을 생성해도 됩니다.
만약에 ESLint가 .gitignore 파일에 이미 나열해놓은 경로를 무시하도록 설정하고 싶다면 ESLint 커맨드를 실행할 때 --ignore-path 옵션을 붙여주면 됩니다.
overrides
프로젝트 내에서 일부 파일에 대해서만 살짝 다른 설정을 적용해줘야 할 때는 어떻게 해야할까요? 그럴 때는 설정 파일의 overrides 옵션을 사용하면 됩니다.
예를 들어, 프로젝트에 자바스크립트 파일과 타입스크립트 파일이 공존한다면 자바스크립트 파일을 기준으로 기본 설정을 하고, 타입스크립트 파일을 위한 설정은 overrides 옵션에 명시할 수 있습니다. 타입스크립트 확장자를 가진 파일에 대해서는 타입스크립트 용 파서와 플러그인과 추천 설정을 사용하도록 세팅해주고 있습니다.
{
"overrides": [
{
"files": "**/*.+(ts|tsx)",
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": ["plugin:@typescript-eslint/recommended"]
}
]
}
만약에 프로젝트 내에 테스트 파일에만 추가적으로 Jest 플러그인과 Testing Library 플러그인에서 추천하는 규칙을 활성하고 싶다면 다음과 같이 설정합니다.
{
"overrides": [
{
"files": ["**/__tests__/**/*", "**/*.{spec,test}.*"],
"env": {
"jest/globals": true
},
"plugins": ["jest", "testing-library"],
"extends": [
"plugin:jest/recommended",
"plugin:jest-dom/recommended",
"plugin:testing-library/react"
]
}
]
}
Default .eslintrc.js
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
},
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
extends: 'standard',
// required to lint *.vue files
plugins: [
'html'
],
// add your custom rules here
rules: {
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}
Inline ignore
/* eslint-disable */
console.log('JavaScript debug log');
console.log('eslint is disabled now');
/* eslint-enable */
Disabling specific ESLint rules
/* eslint-disable no-console, no-control-regex*/
console.log('JavaScript debug log');
console.log('eslint is disabled now');
Ignore a single line
Ignore rules
빌드하면 다음과 같이 에러가 발생될 수 있다.
Module Error (from ./node_modules/eslint-loader/index.js):
/Users/your/Project/c2web/src/components/Canvas/acvPainter.vue
83:5 error Identifier 'hide_event' is not in camel case @typescript-eslint/camelcase
267:11 error Unexpected var, use let or const instead no-var
267:15 error 'width' is already defined no-redeclare
955:17 error 'event_area' is not defined no-undef
967:13 error Unexpected empty method 'created' @typescript-eslint/no-empty-function
✖ 267 problems (266 errors, 1 warning)
82 errors and 0 warnings potentially fixable with the `--fix` option.
각 에러 메시지 우측에 감지된 Rule
이름이 출력된다. 해당 이름의 규칙을 off
상태로 전환하면 된다.
Troubleshooting
Using the export keyword between a decorator and a class is not allowed. Please use export @dec class
instead
다음과 같은 에러 메시지가 출력될 수 있다.
eslint Parsing error: Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.
설정 파일에 다음의 내용을 추가하면 된다.
ESLint Parsing error: Unexpected token
babel-eslint
을 추가하자.
파서를 babel-eslint
로 선택한다.
Resolve Error: typescript with invalid interface loaded as resolver ESLint
eslint-plugin-import 쪽 관련 문제. typescript 적용을 위해 eslint-import-resolver-typescript도 설치해야 한다.
=== SyntaxError: Failed to load plugin '@typescript-eslint' declared in 'package.json': Unexpected token '||=' ===
SyntaxError: Failed to load plugin '@typescript-eslint' declared in 'package.json': Unexpected token '||='
Referenced from: /home/your/Project/ui/package.json
/home/your/Project/ui/node_modules/@typescript-eslint/scope-manager/dist/referencer/ClassVisitor.js:123
withMethodDecorators ||=
^^^
SyntaxError: Unexpected token '||='
at wrapSafe (internal/modules/cjs/loader.js:1029:16)
at Module._compile (internal/modules/cjs/loader.js:1078:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
at Module.load (internal/modules/cjs/loader.js:979:32)
at Function.Module._load (internal/modules/cjs/loader.js:819:12)
at Module.require (internal/modules/cjs/loader.js:1003:19)
at require (internal/modules/cjs/helpers.js:107:18)
at Object.<anonymous> (/home/your/Project/ui/node_modules/@typescript-eslint/scope-manager/dist/referencer/Referencer.js:20:24)
at Module._compile (internal/modules/cjs/loader.js:1114:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
Process finished with exit code -1
node의 버전 설정이 잘못된듯함. PyCharm의 node 설정을 확인해보자.
See also
Favorite site
- ESLint web site
- Configuring ESLint - ESLint - Pluggable JavaScript linter
- Vue.js 공식 ESLint 플러그인 적용하기 (Vue.js, ESLint)
- ESLint와 Prettier 설정 하기 (Vue.js, ESLint, Prettier)
- Vue.js 공식 ESLint 플러그인 적용하기 – Vue.js 한국 사용자 모임 (Vue.js, ESLint)
- VS Code에서 ESlint와 Prettier 함께 사용하기 | feynubrick의 블로그 (VSCode, ESlint, Prettier)
- React + Typescript eslint, prettier설정
- Typescript 프로젝트에 ESLint, Prettier 적용하기