[프론트] Lint & Prettier

Minha Ahn·2023년 9월 27일
1
post-thumbnail

👩🏻‍🏫Lint와 Pretteir를 알아보자.

🤔아직 Lint와 Prettier를 잘 모르겠다.

프로젝트를 시작할 때 하게 되는 첫번째 일은 개발 환경 세팅일 것이다. 나 역시도 몇 번의 개발 환경 세팅을 경험해봤다. 프론트엔드는 개발 환경을 세팅할 때 lint 설정이라는 것을 한다. 지금까지 내가 알고 있는 lint는 여러 사람들이 코드를 짤 때 통일성 있게 코드를 짤 수 있게 도와주는 도구이다. 하지만 이 정도만 알고 있을 뿐 정확한 기능과 세팅 방법, 커스텀 방법도 잘 모른다. 게다가 lint와 함께 언급되는 prettier의 정확한 기능을 아직까지 제대로 인지하지 못한 상태이다. 오늘은 lint와 prettier에 대해서 알아보겠다.

👀Lint를 알아보자

🔍Lint란?

소스 코드를 분석하여 프로그램 오류나 버그, 스타일 오류, 의심스로운 구조체에 표시를 달아놓기 위한 도구를 말한다. 즉,
VSCode의 Plugin에 lint를 검색하면 아래의 이미지와 같이 다양한 플러그인을 찾을 수 있다.

🧐Lint를 왜 쓰는데?

다른 사람과 협업을 할 때 각자 사용하는 코드의 형식이 다르기 때문에 이를 맞춰주기 위해 사용한다. 대부분의 프로그래밍 언어에는 컴파일 과정에서 수행되는 Linter(Lint의 동작을 도와주는 도구)가 기본적으로 내장되어 있지만, 자바스크립트는 컴파일 과정이 없는 인터프리터 언어이기 때문에 Linter가 내장되어 있지 않다. 때문에 런타임 환경에서 에러가 발생할 수 있다. 그렇기 때문에 lint를 이용해 소스 코드를 작성할 때, 사전에 에러들을 발견하고 해결하는 것이 중요하다.

📦Lint 종류

자바스크립트에서 쓸 수 있는 종류

  • JSLint(2002) : 거의 최초의 JS 구문 검사기, 규칙이 매우 엄격하다
  • JSHint(2011) : JSLint보다 조금 규칙이 느슨하다.
  • ESLint(2013) : 모든 규칙을 구성할 수 있고 런타임에 추가 규칙을 정의하거나 로드할 수 있다. JSHint와 JSCS에 있는 기능들이 모두 제공된다.

현재 자바스크립트는 대부분 ESLint를 사용하는 추세이다.
타입스크립트에는 TSLint가 있었으나 deprecated되었고 결국엔 ESLint를 사용하고 있다.

🔍ESLint란?

ESLint는 EcmaScript(JavaScript)와 Lint를 합친 것으로 자바스크립트 문법에서 에러가 발생하면 표시해주는 도구이다. 뿐만 아니라 전반적인 코딩스타일까지 지정할 수 있으므로 협업에 유용한 도구이다.

💡 EcmaScript는 Ecma라는 기구에서 만든 Script라는 뜻이로 표준 JavaScript를 의미한다.

💻예시를 보자

함수 선언의 여러가지 방식

  1. named function declaration (명명 함수 선언)
    가장 대중적인 방법이다.
function fn() {
  // ...
}
  1. anonymous function expression (익명 함수 표현)
    이름없는 함수를 변수에 담은 방식이다.
var fn = function () {
  // ...
}
  1. named function expression (명명 함수 표현)
    명확한 이름이 있는 함수를 변수에 담은 방식이다.
var fn = function test() {
  // ...
}
  1. immediately-invoked expression (즉시 실행 표현)
    즉시 실행 함수로 클로져를 활용할 수 있다.
var fn = (function () {
  // ...
})()

var fn1 = (function (value = 0) {
  let cnt = value
  return function () {
    cnt++
    return cnt
  }
})(1)
fn1() // 2
fn1() // 3
fn1() // 4
  1. function constructor
var fn = new Function()

var fn1 = new Function('a', 'b', 'return a + b')
fn1(2, 6)
  1. arrow function (화살표 함수)
var fn = () => {
  // ...
}

배열을 순회하는 여러가지 방식

const data = [0, 1, 2, 3, 4];
  1. for문 이용하기
for(let i = 0; i < data.length; i++) {
  console.log(i);
}
  1. forEach 이용하기
data.forEach((item) => console.log(item));
  1. for of 이용하기
for(const item of data) {
  console.log(item);
}
  1. for in 사용하기
for(const key in data) {
  console.log(data[key]);
}

여러가지 방식으로 구현할 수 있기 때문에 코드 방식을 일관성 있게 구현할 수 있도록 잡아주는 것이 ESLint가 하는 역할이다.

👀Prettier를 알아보자

🔍Prettier란?

코드 포맷의 통일성을 유지시켜주는 JavaScript 라이브러리이다.
정리하자면 ESLint가 코드 퀄리티를 일관적으로 유지해준다면,
Prettier는 일관적인 코드 스타일을 유지할 수 있게 도와주는 툴이다.

💻예시를 보자

변경 전 코드

function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {
  if(!greeting){return null};
  
    // TODO: Don't use random in render
  let num = Math.floor (Math.random() * 1E+7).toSTring().replace(/\. \d+/ig, "")
  
  return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}>

<strong>{ greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() }</strong>
{greeting.endsWith(",") ? " " : <span style={{color: '\grey'}}>", "</span> }
<em>
{ greeted }
</em>
{ (silent)
	? "."
	: "!"}

</div>;

}

변경 후 코드

function HelloWorld({
  greeting = "hello",
  greeted = '"World"',
  silent = false,
  onMouseOver,
}) {
  if (!greeting){
    return null;
  }
  
  // TODO: Don't use random in render
  let num = Math.floor (Math.random() * 1E+7)
  	.toSTring()
  	.replace(/\. \d+/ig, "");
  
  return (
    <div
    	className="HelloWorld"
    	title={`You are visitor number ${num}`}
		onMouseOver={onMouseOver}
	>
		<strong>
			{greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase()}
		</strong>
		{greeting.endsWith(",") ? (
			" "
		) : (
			<span style={{color: '\grey'}}>", "</span>
		)}
		<em>{greeted}</em>
		{silent	? "." : "!"}
	</div>;

}

📚사용 방법

📕ESLint 사용 방법

▶ ESLint 설치

yarn add -D eslint

-D로 설치하는 이유
-D로 설치하면 package.json에 개발 시에만 사용하는 개발 의존성(devDependencies)으로 기록된다. 개발 의존성으로 설치된 패키지는 --production 옵션을 통해 운영 버전에서는 설치되지 않게 할 수 있다.

▶ 기본 config file 생성

yarn eslint --init
주어진 질문에 답을 하면서 자신에게 알맞은 옵션들을 설정하면 아래와 같은 파일이 만들어진다.

// .eslint.cjs
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "plugin:react/recommended",
        "standard-with-typescript"
    ],
    "overrides": [
    ],
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
      // 원하는 룰 추가
    }
}

// package.json
{
  // ...
  "devDependencies" : {
    // ...
    "eslint-config-standard-with-typescript": "^39.1.0",
    "eslint-plugin-import": "^2.25.2",
    "eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
    "eslint-plugin-promise": "^6.0.0",
    "eslint-plugin-react": "^7.33.2",
  }
}

lint 설정을 위해 중요한 부분은 plugins, extends, rules이다.

  • root
    • default는 true이며, true가 아니라면 eslintrc 파일을 찾을 때 상위의 디렉터리까지 검색하게 된다.
    • 위에서 없는 이유는 root가 없는 이유는 default가 true였기 때문인 것 같다.
  • env
    • 해당 환경에서 정의된 함수나 전역변수를 사용할 수 있게 해준다.
    • "browser": true라면 console.log()를 에러 없이 사용할 수 있다.
    • "node": true를 하게 되면 require를 에러 없이 사용할 수 있다.
  • extends
    • plugin package의 규칙을 그대로 따르고 싶을 때 plugin을 extends에 추가해준다.
    • 가져온 plugin을 일부만 사용할 수 있지만 보통 extends를 통해 plugin을 통째로 가져와 사용한다.
    • plugin의 규칙을 얼마나 어떻게 따를 것인지를 의미하며 보통 recommened를 많이 사용한다.
"extends": [
  "eslint:recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  • parser
    • ESLint가 구문 분석을 위해 어떤 parser를 사용할지 설정해주는 것이다.
    • 기본적으로는 ESpree 파서를 사용하는데, 타입스크립트 구문 분석을 위해서는 @typescript-eslint/parser를 사용하며 설치가 필요하다.
    • yarn add -D @typescript-eslint/parser
  • parserOptions
    • 자바스크립트 언어 옵션을 지정할 수 있다.
"parserOptions": {
  "ecmaFeatures": {
    "jsx": true
  },
    "ecmaVersion": 2020,
    "sourceType": "module"
}
  • plugins
    • plugin 설정을 통해 다른 사람이 만든 규칙을 가지고 올 수 있다.
    • 많이 사용하는 기본적인 plugin으로는 ESLint에서 제공하는 plugin이 있으며
    • react/react/hooks/typescript를 위한 plugin도 있다.
    • airbnb lint plugin도 많이 사용한다.
    • plugins에 추가된다고 해서 바로 적용되는 것은 아니다. extendsrules 설정을 해야 적용할 수 있다.
  • rules
    • plugin의 규칙을 커스텀할 수 있는 곳이다.
    • extends 하여 기본으로 설정된 규칙을 바꾸거나 없앨 수 있고, 기본으로 설정되지 않은 규칙을 추가할 수도 있다.
    • 예) typescript-eslint plugin을 recommend로 extends한 후, recommended에 포함되어 있는 no-explict-any를 없앨 수 있고 recommended에 포함되어 있지 않은 consistent-type-definitions를 설정할 수 있다.

▶ .eslintrc 설정

각종 lint 룰 설정을 위해서는 프로젝트의 루트 디렉터리에 .eslintrc 파일을 만들어서 작성해줘야 한다. 위의 과정을 진행했다면 이미 파일이 생성되었으므로 따로 만들 필요는 없다. .eslintrc 파일의 확장자는 js, json, yml 등 다양하게 설정할 수 있다.

.eslintrc 파일에 사용할 수 있는 확장자 종류는 js, cjs, yaml, yml, json이 있다.
우선 순위는 다음과 같다.
.eslintrc.js > .eslintrc.cjs > .eslintrc.yaml > .eslintrc.yml > .eslintrc.json > package.json

📗Prettier 사용 방법

▶ Prettier 설치

yarn add -D prettier

▶ vscode extension 설치

▶ .prettierrc 설정

ESLint처럼 설정 파일이 필요하며 각종 옵션을 직접 설정할 수 있다.
자세한 설정 항목은 이 곳을 참고하자 여기에도 잘 나와있다

{
  "printWidth": 100,        // 줄 바꿈할 줄 길이
  "tabWidth": 2,            // 들여쓰기 공백 수
  "semi": true,             // 명령문 끝에 세기콜론 인쇄
  "singleQuote": true,      // 인용 부호 ("대신 ')
  "trailingComma": "all",   // 후행 쉼표
  "endOfLine": "auto"       // 줄 끝 (auto: 기존 줄 끝 유지)
  /*
  "singleAttributePerLine": false // HTML, JSX에서 한 줄에 단일 속성 적용
  */
}

▶ ESLint와 Prettier를 함께 사용하기 위해 필요한 것

ESLint의 plugin들의 rule 중 스타일과 관련된 것들도 있기 때문에 종종 Prettier와 충돌하는 일이 생긴다.
이를 방지하기 위해 아래 두 가지 plugin을 이용할 수 있다.

  • eslint-plugin-prettier: prettier를 ESLint plugin으로 추가한다. 즉, prettier가 인식하는 코드 포맷 오류를 ESLint 오류로 출력하도록 할 수 있다. (하지만 사용하지 말자. 특정 상황에서 유용할 수도 있지만 prettier를 직접 실행하는 것보다 느리다.)
  • eslint-config-prettier: ESLint의 코드 포맷과 관련된 rule 중 prettier와 충돌하는 부분을 비활성화할 수 있다.
// .eslintrc
{
  // eslint-config-airbnb의 설정 추가
  // eslint-config-pretteir로 충돌되는 옵션 꺼버린다.
  // prettier를 extends의 마지막에 추가한다.
  "extends": ["airbnb", "prettier"]
}
profile
프론트엔드를 공부하고 있는 학생입니다🐌

1개의 댓글

멋져요!

답글 달기