포매터와 린터

Jeris·2023년 5월 31일
0

코드잇 부트캠프 0기

목록 보기
99/107

1. 코드 스타일이 중요한 이유

코드 스타일이 중요한 이유

연구 결과에 따르면 소프트웨어 개발자들이 약 60%의 업무시간을 코드를 읽고 이해하는데 사용한다고 합니다. 마치 한 사람이 작성한 것처럼 일관된 스타일로 코드를 작성하는 건 효율적인 협업을 위해서 필수적입니다. 가독성이 좋은 코드는 읽는데 작은 노력과 적은 시간이 들기 때문입니다.

코딩 컨벤션

수많은 기업들과 프로젝트들이 코딩 컨벤션(Coding Convention)을 정해놓고 사용합니다. 코딩 컨벤션은 개발자들이 논의를 통해 어떤 스타일로 코드를 작성할지 약속해 놓은 규칙, 매뉴얼입니다.

JavaScript Standard Style
Google JavaScript Style Guide
Github - airbnb/javascript: JavaScript Style Guide
코딩컨벤션 | TOAST UI :: Make Your Web Delicious!

포매터와 린터

실제 코딩 컨벤션 문서는 전부 외워서 사용하기가 어렵습니다. 그리고 외우는 사람이 있더라도 실수할 확률이 높습니다. 이걸 지켰는지 확인하면서 일일이 신경쓰는 것도 비효율입니다. 그래서 개발자들은 이것도 대신해 주는 개발 도구를 사용합니다. 바로 포매터(Formatter)와 린터(Linter)입니다.

규칙을 미리 정해두면, 포매터는 코드 스타일을 검사/수정(포매팅)해 주고, 린터는 코드의 구조를 검사해서 잘못 작성된 코드가 없는지 확인(정적 분석; Static Analysis)해 줍니다. 포매터와 린터에 규칙만 잘 정해두면 마치 한 사람이 작성한 코드처럼 만들 수 있습니다.

함께 사용하는 자동화 도구들

포매터와 린터도 사람이 매번 실행하려니 비효율적입니다. 검사하는 걸 잊어버릴 때도 있습니다 그래서 이것 마저도 대신해 주는 자동화 도구들을 사용합니다.

Husky
최근에는 자바스크립트로 개발하는 경우에 husky라고 하는 패키지를 사용해서 포매터와 린터를 자동으로 실행하는 경우가 많습니다. husky를 사용하면 커밋을 하기 전이나 푸시를 하기 전에 포매터와 린터를 실행해서 자동으로 코드를 검사하도록 할 수 있습니다. 참고로 Husky는 Git에서 제공하는 깃 훅(Git Hooks)이라는 기능을 쉽게 사용할 수 있도록 해주는 패키지이기 때문에, 꼭 husky를 사용하지 않더라도 Git의 기능으로 이런 자동화를 할 수 있습니다.

Github Action
자동화 스크립트를 내 컴퓨터에서만 실행하는 게 아니라, 깃허브 같은 원격 저장소에서도 실행할 수 있습니다. 린터를 실행하거나 하는 일도 깃허브에서 실행할 수 있습니다. 최근에는 깃허브에서 기본적으로 제공하는 Github Action이라는 걸 많이 사용 합니다.


2. Editor Config

EditorConfig

VS Code에서는 환경 설정을 하면 내가 원하는 코드 스타일을 지키도록 할 수 있습니다. 예를 들어서 들여쓰기를 스페이스 2칸으로 하고, 따옴표는 반드시 홑따옴표만 쓰도록 할 수 있습니다.

그런데 사람들이 전부 똑같이 VS Code를 쓰지는 않을 겁니다. WebStorm을 쓰는 사람도 있고, Sublime Text를 쓰는 사람들도 있습니다. 이 모든 사람들에게 설정을 공통적으로 적용할 수 있는 방법이 있는데, 바로 EditorConfig입니다.

EditorConfig는 에디터의 설정을 코드로 할 수 있게 해 주는데요. 예를 들어서 아래와 같은 .editorconfig 파일을 만들고 프로젝트 최상위 폴더에 배치해 두면, 기본적인 에디터 설정을 할 수 있습니다. 이렇게해 두면 프로젝트 소스코드만 다운 받으면 별도로 에디터 설정을 할 필요 없이 기본적인 코드 스타일을 설정할 수 있다는 장점이 있죠.

.editorconfig

root = true

[*]
indent_style = space          # 들여쓰기에 스페이스 사용
indent_size = 2               # 들여쓰기 크기는 스페이스 2개로 쓰기
charset = utf-8               # 파일 인코딩은 utf-8
insert_final_newline = true   # 파일 맨 마지막에 빈 줄 추가하기

3. Prettier

패키지로 설치하기

내 프로젝트에 devDependenciesprettier 라는 패키지를 설치합니다.

npm install --save-dev prettier

그리고 .prettierrc.json 라는 파일을 만듭니다. 이 파일은 Prettier에서 사용할 규칙을 적은 설정 파일입니다. 예를 들어서 아래 파일은 “매번 마지막에 콤마를 추가하기”, “들여쓰기 크기는 2”, “세미콜론은 쓰지 않기”, “홑따옴표만 쓰기”를 설정한 겁니다. 이런 규칙의 목록은 Prettier 공식 문서의 Options에서 확인할 수 있습니다.

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true
}

prettier 패키지를 직접 실행할 수도 있지만, NPM 스크립트를 통해 사용하는 걸 권장합니다.
아래의 예시에서 --write 는 파일을 덮어써서 수정하겠다는 의미이고, src/**/*.jssrc 디렉토리 아래에 있는 모든 자바스크립트 파일을 의미합니다.

package.json

{
  "name": "formatter-and-lint",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "prettier": "prettier --write src/**/*.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "prettier": "^2.8.8"
  }
}

예를 들어서 src/test.js 라는 파일에 섭씨-화씨를 변환하는 코드를 저장하고 npm run prettier를 실행하면, 아래처럼 Prettier는 우리가 정한 규칙에 따라 파일을 수정합니다.

src/test.js

function c2f(value){return value*9/5+32}

참고하면 좋은 자료

[자바스크립트] Prettier로 코딩 스타일 통일하기


4. ESLint

React(Create React App)에서 사용하기

프로젝트 폴더에서 터미널을 열고, ESLint에서 제공하는 도구를 사용해서 초기화 합니다.

npm init @eslint/config

만약에 이 명령어를 처음 실행했다면 아래처럼 @eslint/create-config 라는 패키지를 설치할 거나고 물어보는데, y를 입력합니다.

Need to install the following packages:
  @eslint/create-config@0.4.3
Ok to proceed? (y)

설치 목적을 선택합니다. 일단 문법을 검사하고, 문제를 찾아내는 것을 선택합니다.

? How would you like to use ESLint? … 
❯ To check syntax and find problems
  To check syntax, find problems, and enforce code style
  To check syntax only

모듈 문법도 설정합니다.

? What type of modules does your project use? … 
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these
  

그 외의 필요한 설정을 선택합니다.

성공적으로 세팅했다면 package.jsondevDependencies에 아래 두 패키지가 추가되어 있을 것입니다.

"eslint": "^8.39.0"
"eslint-plugin-react": "^7.32.2"

이제 NPM 스크립트를 추가해 주세요.

{
  ...
  "script": {
    "lint": "eslint src/**/*.js",
    ...
  }
}

src 폴더 아래에 있는 모든 자바스크립트 파일에 eslint를 실행하도록 했습니다.

npm run lint 를 실행해보면 아래처럼 eslint가 실행됩니다.

.eslintrc.js라는 파일은 eslint에 적용할 규칙을 코드로 작성한 파일입니다. 이걸 수정하면 적용할 규칙을 바꿀 수 있습니다.

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ['eslint:recommended', 'plugin:react/recommended'],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['react'],
  rules: {},

Next.js에서 사용하기

Basic Features: ESLint | Next.js

Next.js에서는 기본적으로 ESLint를 별도의 설정 없이 사용할 수 있습니다. .eslintrc.js 파일을 만들고 npm run lint 를 실행하면 됩니다.

자주 쓰이는 설정들

.eslintrc.jsrules 라는 프로퍼티에서 객체를 만들고, 그 객체에서는 각 프로퍼티의 이름으로 규칙의 이름을 쓴 다음 규칙을 설정할지 말지를 결정합니다. 어떤 규칙을 쓸 수 있는지는 공식 문서의 Rules Reference를 찾아보면 됩니다.

예를 들어서 세미콜론을 쓸 건지 정하는 규칙(공식 문서 설명)은 semi 입니다. 공식 문서에 따르면 always 라는 값을 쓰면 항상 세미콜론을 쓰고, never 라는 값을 쓰면 항상 세미콜론을 생략합니다. 이런 식으로 rules 에다가 규칙을 설정하면 됩니다.

`.eslintrc.js

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
  ],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['react'],
  rules: {
    semi: ['error', 'never'],
  },
};

리액트 버전 17 이상을 쓰고 있다면 매번 import React from 'react'; 라는 코드를 쓸 필요가 없습니다. 그래서 이것과 관련된 코드를 eslint가 검사하지 않도록 react/jsx-runtime 이라는 설정을 상속해 주어야 합니다.(링크 쉽게 말해서 다른 eslintrc 파일을 현재 eslintrc 파일에서 불러와서 쓰는 것입니다.

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    **'plugin:react/jsx-runtime',**
  ],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['react'],
  rules: {},
};

그 밖에도 많은 사람들이 규칙을 하나하나 정의하기 보다는 다른 사람들이 만들어 놓은 규칙에 일부만 수정해서 사용하는 경우가 많습니다.

npm: eslint-config-airbnb

eslint-config-airbnb라는 패키지는 앞에서 살펴 본 plugin:react/jsx-runtime 이랑 마찬가지로 미리 만들어 놓은 eslintrc 파일입니다. 이 패키지를 설치한 다음 프로젝트에서 불러와서 사용할 수 있습니다. 패키지 공식 문서의 설명에 따라 eslint-config-airbnb 패키지를 설치하고, extends에 추가해야 합니다.

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    **'airbnb',
    'airbnb/hooks',**
  ],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['react'],
  rules: {},
};

airbnb 는 에어비앤비의 코딩 컨벤션을 eslint 규칙으로 만들어 둔 것입니다. 그리고 airbnb/hooks는 리액트 훅을 사용하는 규칙을 정해놓은 것입니다. 실제로 어떤 규칙들이 들어가 있는지는 깃허브에서 확인할 수 있습니다. (링크1, 링크2)

참고 자료

JS코드를 깔끔하게 해주는 ESLint 알아보기! (적용방법과 상세 옵션)


5. Stylelint

앞에서 살펴 본 ESLint가 자바스크립트의 구문을 분석해 검사하는 도구라면, CSS를 위한 린터인 Stylelint도 있습니다.

Home | Stylelint

참고로 일반적인 CSS 문법이 아니라, SCSS같은 프리프로세서 문법이라던지 Styled-Components 같은 CSS-in-JS 라이브러리에서도 Stylelint를 위한 플러그인을 만들어서 제공하는 경우도 있습니다.

npm: stylelint-config-standard-scss
styled-components: Tooling


6. Husky

npm: husky

깃 훅(Git Hooks) 기능을 손쉽게 쓰도록 도와주는 NPM 패키지입니다.

패키지를 설치하고 공식 문서의 설명처럼 prepare 라는 NPM 스크립트로 husky install 을 추가한 다음에 한 번 실행해 줍니다. (참고로 여기서 첫 번째 줄은 package.json 파일에서 scripts 안에다가 preprare: "husky install" 을 추가하는 명령어 입니다.)

npm pkg set scripts.prepare="husky install"
npm run prepare

이제 pre-commit 훅을 추가합니다.

npx husky add .husky/pre-commit "npm run lint"

코드를 수정하고 커밋을 해 보면, npm run lint 를 먼저 실행하고, 만약에 린트가 깨진다면 커밋이 생성되지 않습니다. 이런 식으로 Husky를 이용하면 깃 훅을 활용해 여러가지 명령어들을 실행할 수 있습니다.

참고자료

husky: git hook을 통한 테스트 및 린트 자동화


Feedback

  • 참고 자료로 포스팅해보자.
  • 실제로 어떤 formatter/linter를 사용하는지 찾아보자.

Reference

profile
job's done

0개의 댓글