Javascript 문법을 고쳐주는 ESLint

5 분 소요

왜 사용할까요?

내가 작성한 코드가 잘못된 패턴이거나, 문법이 틀린 경우 그 부분을 찾아내서 고쳐주기 때문입니다. JSLint, JSHint와 같이 다른 JavaScript 정적 분석 도구들도 있지만, ESLint가 수정하기가 쉽고 확장성이 뛰어나 많이 쓰이고 있는 추세라고 합니다.

설치하기

npm

npm install eslint --save-dev

yarn

yarn add eslint --dev

원하는 옵션 추가하기

파일 형식에따른 정의방법

ESLint는 3가지 형식으로 설정을 정의할 수 있습니다.

JS/JSON 형식

.eslintrc/.eslintrc.js/.eslintrc.json 파일을 사용하는 경우

{
  "env": {
    "browser": true,
    "node": true
  }
}

YAML 형식

.eslintrc.yaml/.eslintrc.yml 파일을 사용하는 경우

env:
  browser: true
  node: true

package.json 형식

package.json 파일 안에 설정을 정의하는 경우
(eslintConfig 속성으로 파일을 대체할 수 있습니다.)

{
  "name": "mypackage",
  "version": "0.0.1",
  "eslintConfig": {
    "env": {
      "browser": true,
      "node": true
    }
  }
}

환경의 정의하는 속성 (“env”)

ESLint는 실행환경을 위한 전역 변수 묶음을 제공하고 있습니다. 묶음의 종류는 다음과 같습니다.

browser (브라우저)

브라우저에서 사용되는 전역 변수를 사용할 수 있습니다.
(window, alert, console …)

node (Node.js)

Node.js 에서 사용되는 전역 변수를 사용할 수 있습니다.
(process, console …)

commonjs (CommonJS)

CommonJS 전역 변수를 사용할 수 있습니다.
Browserify/WebPack를 사용하는 브라우저 전용 코드에 사용합니다.

shared-node-browser (Node.js와 브라우저)

Node.js와 브라우저 둘다 해당하는 전역 변수를 사용할 수 있습니다.
(console …)

es6 (ECMAScript 6)

ecmaVersion 파서 옵션이 6 으로 설정됩니다.
모듈을 제외한 모든 ECMAScript 6 전역 변수를 정의합니다.

  • let
  • const

es2017 (ECMAScript 8)

ecmaVersion 파서 옵션이 8 으로 설정됩니다.
모든 ECMAScript 2017 전역 변수를 정의합니다.

  • async
  • await
  • SharedArrayBuffer
  • Object.values
  • Object.entries
  • Object.getOwnPropertyDescriptors
  • String.prototype.padStart

es2020 (ECMAScript 11)

ecmaVersion 파서 옵션이 11 으로 설정됩니다.
모든 ECMAScript 2020 전역 변수를 정의합니다.

  • String.prototype.matchAll
  • import()
  • import.meta
  • BigInt
  • Promise.allSettled
  • globalThis
  • for-in mechanics
  • Optional chaining (a?.b.?c)
  • Nullish coalescing Operator (actualValue ?? defaultValue)
  • export * as ns from “mod”;

es2021 (ECMAScript 12)

ecmaVersion 파서 옵션이 12 으로 설정됩니다.
모든 ECMAScript 2021 전역 변수를 정의합니다.

  • String.prototype.replaceAll()
  • Promise.any()
  • WeakRefs
  • Logical assignment operators (||=, &&=, ??=)
  • Underscores (_) as separators in number literals and bigint literals (1_222_333 = 1222333)

worker (web workers)

web workers 전역 변수를 정의합니다.
(Worker, SharedWorker …)

amd (require, define)

amd 사양에 따라서 require, define 전역 변수를 정의합니다.

mocha (테스트)

mocha 테스트 라이브러리의 전역 변수를 정의합니다.
(describe, it …)

jasmine (테스트)

jasmine 테스트 라이브러리의 전역 변수를 정의합니다.
(describe, it …)

jest (테스트)

jest 테스트 라이브러리의 전역 변수를 정의합니다.
(describe, it …)

phantomjs (브라우저)

PhantomJS 브라우저의 전역 변수를 정의합니다.
(page, phantom …)

protractor (테스트)

protractor 테스트 라이브러리의 전역 변수를 정의합니다.
(describe, it …)

qunit (테스트)

QUnit 테스트 라이브러리의 전역 변수를 정의합니다.
(QUnit …)

jquery (제이쿼리)

jQuery 라이브러리의 전역 변수를 정의합니다.
(jQuery, $)

prototypejs (타입)

Prototype.js 라이브러리의 전역 변수를 정의합니다.

shelljs (스크립트)

ShellJS 라이브러리의 전역 변수를 정의합니다.
(cat, cd, chmod, cp …)

meteor (빌드/배포)

Meteor 라이브러리의 전역 변수를 정의합니다.
(Meteor …)

mongo (MongoDB)

MongoDB 전역 변수를 정의합니다.
(MongoClient …)

applescript (AppleScript)

AppleScript 전역 변수를 정의합니다.
(applescript.execString …)

nashorn (JAVA 8)

Java 8 Nashorn 전역 변수를 정의합니다.
(Java, Java.type …)

serviceworker

Service Worker 전역 변수를 정의합니다.
(ServiceWorkerContainer …)

atomtest (테스트)

Atom test helper 전역 변수를 정의합니다.

embertest (테스트)

Ember test helper 전역 변수를 정의합니다.
(moduleFor, moduleForComponent …)

webextensions (웹 익스텐션)

WebExtensions 전역 변수를 정의합니다.
(tabs, bookmarks …)

greasemonkey (파이어폭스 익스텐션)

GreaseMonkey 전역 변수를 정의합니다.
(unsafeWindow …)

플러그인으로 원하는 옵션 추가하기

JS/JSON 형식

.eslintrc/.eslintrc.js/.eslintrc.json 파일을 사용하는 경우

{
  "plugins": ["myPlugin"],
  "env": {
    "myPlugin/env_set_1": true
  }
}

package.json 형식

package.json 파일 안에 설정을 정의하는 경우

{
  "parserOptions": {
    "plugins": ["myPlugin"],
    "env": {
      "myPlugin/env_set_1": true
    }
  }
}

YAML 형식

.eslintrc.yaml/.eslintrc.yml 파일을 사용하는 경우

plugins:
  - myPlugin
env:
  myPlugin/env_set_1: true

사용자가 추가하는 전역 변수 (globals)

값이 true인 경우에는 값을 덮어쓸 수 있고, false인 경우에는 변경이 불가능합니다.

{
  "globals": {
    "var1": true,
    "var2": false
  }
}

언어 파싱 옵션 (parserOptions)

{
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
        "jsx": true
    }
  },
}

ecmaVersion (사용할 자바스크립트 버전)

기본값은 5 이고, 원하는 버전으로 설정할 수 있습니다.

sourceType (코드의 형태 기본/모듈)

기본값은 “script” 이고, 코드가 모듈의 형태(export, import)를 가지고있는 경우에는 “module” 로 값을 변경합니다.

ecmaFeatures (언어 확장 기능)

  • globalReturn : 전역 스코프의 사용 여부 (node, commonjs - module)
  • impliedStric : strict mode 사용 여부
  • jsx : jsx 사용여부

코드의 형식에 대한 설정 (Rules)

버그와 코드의 형식에 대한 설정을 나타냅니다. 하지만 prettier와 함께 사용하는 경우에는 코드의 형식에 대한 차이가 발생할 수 있습니다.

이러한 경우를 막기 위해 코드의 형식에 대한 설정은 모두 prettier 설정파일의 값이 적용되도록 eslint-plugin-prettier 패키지를 함께 사용합니다. 다음 명령어를 통해서 플러그인을 설치할 수 있습니다.

eslint-config-prettier 설치하기

# npm
npm install --save-dev eslint-config-prettier

# yarn
yarn add --dev eslint-config-prettier

플러그인 및 설정 세트를 적용하기

eslint-plugin-prettier 패키지에서는 플러그인과 그에 해당하는 설정을 하나의 묶음으로 제공하고 있습니다. 따라서 다음과 같이 한줄만 추가하는 것으로 prettier 와 eslint 의 설정을 잘 맞출 수 있습니다.

{
  "extends": ["plugin:prettier/recommended"]
}

extends 의 속성에 해당하는 정확한 내용은 다음과 같습니다.

{
  "extends": ["prettier"],
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error",
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off"
  }
}

ESLint 적용 범위 제한하기

.eslintignore 파일을 사용하여 ESLint 적용 범위를 제한할 수 있습니다. 외부 패키지들을 모아놓은 node_modules 폴더와 배포할 파일을 저장하는 dist 또는 build 폴더에는 ESLint가 적용될 필요가 없기 때문에 다음과 같이 추가해 줍니다.

node_modules/*
dist/*

Typescript를 사용하고 싶다면?

Typescript 플러그인 설치

ESLint 플러그인

# ESLint 라이브러리
yarn add --dev eslint

# ESLint TypeScript 파서
yarn add --dev @typescript-eslint/parser

# ESLint TypeScript 규칙을 포함하는 플러그인
yarn add --dev @typescript-eslint/eslint-plugin

Prettier 플러그인

# Prettier 라이브러리
yarn add --dev prettier

# Prettier 와 충돌이 발생하는 ESLint 설정을 비활성화
yarn add --dev eslint-config-prettier

# Prettier 코딩 규칙을 ESLint와 동일하게 적용
yarn add --dev eslint-plugin-prettier

타입스크립트 파서 및 확장파일 지정

CRLF/LF 설정

윈도우와 맥의 endOfLine 속성의 CRLF 와 LF 차이를 잡기 위해서 다음과 같은 git 명령어를 실행합니다.

git config --global core.autocrlf input

파서/확장 설정

{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint", // v8.0.0 버전 이상에서는 제거
    "plugin:prettier/recommended"
  ],
  "rules": {
    "prettier/prettier": 0
  }
}

husky 설치 및 활성화

npx husky install 명령어를 통해 husky를 활성화하면 .husky 폴더가 생성됩니다. 이제 깃 훅을 등록하여 사용할 수 있습니다.

yarn add --dev husky
npx husky install

lint-staged 설치

깃 훅 중에서 lint-staged 패키지를 설치합니다.

npx lint-staged -y

훅 스크립트 추가

설치된 lint-staged 패키지를 실행하는 훅 스크립트를 pre-commit 이라는 이름으로 추가해줍니다.

npx add .husky/pre-commit "npx lint-staged"

린트 훅 설정파일 추가 (.lintstagedrc.json)

.lintstagedrc.json 설정파일을 생성한 후, 폴더 경로에 따라서 어떻게 커맨드를 적용할지 입력해줍니다.

{
  "src/**/*.{js,ts,tsx}": ["eslint \"**/*.{js,ts,tsx}\" --fix"],
  "src/**": ["prettier --write ."]
}

린트 스크립트 추가 (package.json)

마지막으로 자동으로 훅을 활성화 할 수 있도록 “prepare”: “husky install” 스크립트를 추가해줍니다.
이제 커밋을 할 때마다 린트 훅이 실행되어서 코드를 수정해 줍니다.

{
  "scripts": {
    "lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
    "prepare": "husky install"
  }
}