프로젝트에 코드 스타일 셋팅하기(eslint, prettier, stylelint)

Seal Park·2022년 6월 12일
5

처음 개발하던 때에..

맨 처음 혼자서 토이 프로젝트를 할 때, 어떤 곳에서는 문자열 선언에 double quote를 사용하고, 또 어떤 곳에서는 single quote를 사용하는 식으로 문자열 선언이 일관되지 않았어요. 그래서 처음에 single quote를 모두 double quote로 바꾸었는데, 막상 다시 생각해보니 별로인 것 같아서 다시 모두 single quote로 바꾸었던 기억이 나네요 😂.. css에서는 가상 선택자를 잘못 타이핑 해서 적용이 되지 않을 때도 있었고, 간혹 오타가 발생하면 즉시 눈에 보이니 수정하는 경우도 있지만, 가끔 지나치는 경우에는 그대로 코드가 올라가는 경우도 있었어요.

당장 실행되는데에는 문제가 없지만, 추후에 문제가 있을법한 문법 들을 잡아주는 도구가 있으면 좋겠다는 생각도 했었어요. 실수로 비교연산자로 ‘==’를 사용한다던가, 배열을 선언할 때에는 new Array()가 아닌 리터럴로 선언을 한다던지.. 등등이요. 당시 처음에 혼자 공부했을 때에는 이 방법이 맞는지에 대해 굉장히 궁금했었거든요.

그래서 코드의 일관성을 설정하고, 일관성에 어긋나면 실시간으로 알려주는, 때에 따라서 자동으로 잘못된 부분을 알아서 변경시켜주는 것이 있으면 좋겠다는 생각을 하게 됩니다.

Eslint, Prettier

그리고나서 발견한 게 eslint, prettier에요. eslint 공식문서에 들어가면, 가장 처음으로 ‘Find and fix problems in your JavaScript code라고 설명해요. 말 그대로 자바스크립트 코드에서 문제를 찾고 수정해주는 도구입니다. 저의 생각이지만, eslint의 뜻은 es + lint가 아닐까 조심스레 예측해 봅니다. es는 ECMAScript이고, Lint는 보풀이라는 뜻인데, 아마도 자바스크립트 코드 내에서 잘못된 부분이 있으면 옷에서의 보푸라기처럼 에러 하이라이팅을 띄우고, 제거를 하면 옷에서의 보풀을 떼는 듯한 이미지를 연상하면, eslint가 어떤 역할을 하는지 와닿을 것 같아요.

그리고 prettier는 코드 포맷터(code formatter)에요. 일반적으로 자바스크립트 문법과는 상관 없지만, 코드의 포맷을 강제적으로 설정하여, 포맷을 따르지 않으면 에러 하이라이팅을 띄우는 도구에요. prettier 공식문서에도 가보면, ‘An opinionated code formatter’라고 소개합니다. eslint에 비해 적은 옵션이지만, 코드 포맷을 설정하는 데에는 충분한 옵션들 입니다.

Eslint 설치하고, 적용해보기

먼저 eslint를 설치해보겠습니다. 적용하려면 Node.js가 설치 되어있어야 합니다. 지금 사용하는 버전으로 eslint 설치가 가능한지는 링크를 통해서 확인할 수 있습니다.

먼저 프로젝트를 생성하고 다음과 같은 명령어를 입력합니다

npm install eslint --save-dev

// or

yarn add eslint --dev

라이브러리가 설치되면, eslint 설정이 필요한데요, 아래와 같은 명령어를 입력하면 cli에서 몇가지 선택사항이 있는데, 해당 프로젝트에 맞는 설정을 통해 초기화 작업을 진행하면 되겠습니다.

npm init @eslint/config

// or

yarn create @eslint/config

정상적으로 완료가 되면 가장 상위 루트에 .eslintrc 파일이 생성된 것을 볼 수 있습니다! 이 안에서 다양한 설정이 가능한데요, 천천히 살펴보면서 어떠한 설정을 할 수 있을지 간단하게 알아보도록 해요.

  • env(Environment) 어떤 환경에서 eslint를 가정하는 지를 설정합니다. 브라우저 환경인 지(browser), 아니면 노드 환경인 지(node), es 버전은 몇 버전을 사용하는지를 설정할 수 있습니다
  • parser eslint에서 기본값으로 espree라는 parser를 사용하고 있습니다. 타입스크립트를 사용한다면 @typescript-eslint/parser를, babel파서를 감싼 parser를 사용하고싶다면 @babel/eslint-parser를 설정합니다.
  • plugins 추가적으로 규칙, 환경, 구성 등을 정의한 서드 파티 라이브러리들을 plugins에서 설정할 수 있어요.
  • rules eslint의 규칙을 설정할 수 있습니다. 규칙은 총 세가지로 표현할 수 있는데, ‘off’ 또는 0, ‘warn’ 또는 1, ‘error’ 또는 2로 설정이 가능하며 해당 파일의 주석으로 규칙을 설정할 수 있고, .eslintrc 파일 내에서 설정할 수 있습니다.
  • extends 구성 파일(configuration file)을 해당 영역에 설정을 하면, rules, plugins 등 또 다른 구성 파일의 모든 특성을 상속받을 수 있으며, 모든 옵션들을 수정할 수 있습니다.

.eslintrc 예시

// react with typescript, eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
	parser: [
		'@typescript-eslint', // @typescript-eslint/parser
		'import', // eslint-plugin-import
	plugins: [
		'react', // eslint-plugin-react
		'@typescript-eslint' // @typescript-eslint/eslint-plugin
	],
  extends: [
    'eslint:recommended', // eslint
    'plugin:react/recommended', // eslint-plugin-react
    'plugin:@typescript-eslint/recommended', // @typescript-eslint/eslint-plugin
  ],
  rules: {
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'react/prop-types': 'off',
  },
	// ... 이외의 여러가지 설정들
};

위의 구현 부분을 보면 주석 부분은 모두 라이브러리 이름이에요. 그런데 막상 보면 라이브러리 이름과 설정하는 부분의 이름이 다르지 않나요? 이 부분들은 eslint에서 편의를 위해 제공하는 기능입니다.

  • parser: eslint-plugin을 생략 할 수 있다.
  • plugin : eslint-plugin을 생략 할 수 있다.
  • extends
    • plugin인 경우 prefix로 plugin:을 붙인다
    • 그 외에는 eslint-config를 생략 할 수 있다.

Prettier 설치하고, 적용해보기

이제 코드 포맷터인 prettier를 설치해보겠습니다. 먼저 cli에서 해당 프로젝트에 라이브러리를 설치합니다.

npm install --save-dev --save-exact prettier

// or 

yarn add --dev --exact prettier

가장 상위 루트에 .prettier.json이라는 파일을 생성합니다.

이제 .prettier.json 파일에 옵션들을 설정해보려는데요, 그 전에 옵션에 대해 간단하게 알아보고나서 적용해보도록 하겠습니다.

  • printWidth(number): 각 라인의 길이를 지정합니다. 명시한 길이를 넘으면 줄넘김 처리를 해야합니다. 기본값은 80입니다.
  • tabWidth(number): 각 탭(들여쓰기)의 공백 길이를 지정합니다. 기본은 2입니다.
  • useTabs(boolean): 들여쓰기를 탭으로 할 지를 지정합니다. 기본값은 false입니다.
  • semi(boolean): 세미콜론을 설정할지를 지정합니다. 기본값은 true입니다.
  • singleQuote(boolean): single quote(홑따옴표)를 사용할지를 지정합니다. 기본값은 true입니다.
  • trailingComma(string): 객체, 배열의 경우 여러 줄로 작성해야 하는 경우 쉼표(반점, comma)를 사용할지를 결정 합니다. none, es5, all이 있습니다. 기본값은 es5입니다.
    • none: 설정 안 함
    • es5: 객체, 배열에 설정
    • all: 가능한 모든 곳에 설정합니다. (e.g.. 함수의 파라미터)
  • arrowParens(string): 화살표 함수를 사용하는 경우, 파라미터가 들어가는 자리의 갯수가 하나인 경우 괄호를 입력하는지 여부를 설정합니다. 기본값은 always입니다.
    • always: 항상 괄호를 명시한다.
    • avoid: 가능하면 괄호를 생략한다.

.prettierrc 예시

{
	"printWidth": 80,
	"tabWidth": 2,
	"useTabs": true,
	"semi": true,
	"singleQuote": true,
	"trailingComma": "all",
	"arrowParens": "always"
}

Eslint에 Prettier 설정하기

.prettierrc 파일에서 설정을 마쳤다면, 마지막으로 eslintprettier를 설정해야해요. 그러기 위해서는 라이브러리 설치가 필요합니다.

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

// or 

yarn add --dev eslint-config-prettier eslint-plugin-prettier

그 다음 .eslintrc 파일에서 추가 설정을 해주어야 합니다.

// react with typescript, eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
	parser: [
		'@typescript-eslint', // @typescript-eslint/parser
		'import', // eslint-plugin-import
	plugins: [
		'react', // eslint-plugin-react
		'@typescript-eslint', // @typescript-eslint/eslint-plugin
		// #1 plugins에 prettier 설정
		'prettier'
	],
  extends: [
    'eslint:recommended', // eslint
    'plugin:react/recommended', // eslint-plugin-react
    'plugin:@typescript-eslint/recommended', // @typescript-eslint/eslint-plugin
		// #2 extends에 prettier 설정
    'prettier', // eslint-config-prettier
  ],
  rules: {
		// #3 rules에 prettier의 코드 포맷이 어긋나는 경우 error highlighting 설정
		'prettier/prettier': ['error'],
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'react/prop-types': 'off',
  },
	// ... 이외의 여러가지 설정들
};

1번, 2번을 보면 plugins, extendsprettier를 설정하고, rulesprettier 규칙이 어긋날 시 어떻게 표시할 지를 설정합니다.

VSCode에서 Extentions 설치

사용하는 에디터에서 실시간으로 작성하는 코드의 에러를 확인하고 싶다면, prettier, eslint를 설치하세요. 그러면 바로 코드 작성 단계에서 확인이 가능합니다.

vscode에서 좌측 1번을 클릭한 후, 입력 칸에 eslint를 입력하시면 아래 목록에 eslint가 있어요. 그 영역을 클릭하면 오른쪽과 같은 화면에 install 버튼이 있습니다. 3번을 보시면 버튼이 있는데, 클릭하면 vscode에 eslint가 설치됩니다.

prettier도 마찬가지로 설치하시면 에디터에서 확인이 가능해요.

StyleLint

stylelint는 좀 나중이 되어서야 알았어요. stylelintcss 문법을 잡아주고, 코드 컨벤션 설정까지 가능한 도구입니다. 공식문서에 보면 ‘A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.’라고 소개해요.

공식문서에 따르면, 170개 이상의 규칙들(rules)과 자동 포맷팅을 지원하며, 사용자 지정 플러그인까지 가능하여, 직접 만들 수 있거나, 잘 만들어진 플러그인을 가져와 설정할 수 있습니다.

아무래도 프론트엔드 개발을 하다보면 잘못 된 css 코드를 작성할 수 있고, 여러 명이서 작업하다보면 일관된 코드 포맷이 필요할 수도 있다고 생각해요. 그렇다면 stylelint를 설정하는 것도 좋은 대안이 될 수 있다고 생각합니다!

VSCode에서 Stylelint Extension 설치하기

위의 eslint 설치 방법처럼 stylelint를 설치하시면 마찬가지로 코드 작성단계에서 실시간으로 에러를 확인할 수 있습니다.

Stylelint 설치하고, 적용해보기

먼저 라이브러리를 설치합니다.

npm install --save-dev stylelint stylelint-config-standard stylelint-config-prettier

// or 

yarn add --dev stylelint stylelint-config-standard stylelint-config-prettier

그리고 대상 프로젝트 최 상단에 .stylelintrc.json이라는 폴더를 생성한 후 파일에 아래와 같은 코드를 작성합니다.

{
  "extends": ["stylelint-config-standard", "stylelint-config-prettier"]
}

실제로 stylelint가 정상 작동하는지 간단하게 테스트를 해볼게요. index.css파일을 생성하고 일부러 작성을 틀리게 해볼게요.

의도적으로 width500px 사이의 콜론을 누락하여 작성해 볼게요. width: 500px;width 500px;로 작성했을 때 Unknown word 라는 에러 메세지를 보여주고 있습니다. 이제 오타를 수정하면,

에러 하이라이팅 없는 것을 확인할 수 있어요. stylelint를 사용함으로써 보다 더 안전한 코드를 작성할 수 있게 됩니다.

이외에도 .stylelintrc.json 파일 내에서 추가로 설정할 수 있는 부분들이 있습니다.

  • extends 위에서 설치했던 stylelint-config-… 라이브러리 이외에도 다양한 라이브러리들을 설치할 수 있습니다. 위의 예시는 css 이지만, scss, html, vue에 문법 규칙이 있다면 추가로 확장할 수 있습니다.
  • customSyntax 사용자 지정(custom) 문법을 설정할 수 있습니다. 위의 목록에 해당하지 않는다면, customSyntax에 설정할 수 있습니다.
  • overrides 사용자 지정이 두 개 이상이라면 overrides를 통해 설정이 가능합니다. 예를 들어 css파일과 css-in-js파일의 경우, overrides를 통해 각각의 스타일 관련 린트를 적용시킬 수 있습니다.
  • rules stylelint의 규칙을 설정할 수 있습니다. 각각 rules마다 설정이 조금씩 달라서, 문서를 보면서 설정해야 한다는 특징이 있습니다.

css-in-js를 사용할 때의 .stylelintrc 파일

css-in-js(e.g.. emotion, styled-component)를 사용할 때에는 아래와 같은 설정이 필요합니다.

{
	"overrides": [
		{
			"customSyntax": "@stylelint/postcss-css-in-js",
			"files": ["**/*.styles.ts"] // 각 프로젝트의 컨벤션에 맞게 대상 파일 포맷 설정
		}
	],
	"extends": [
		"stylelint-config-standard",
		"stylelint-config-prettier",
	],
	"rules": {
		// ...
	}
}

0개의 댓글