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

자바스크립트에서 최근 가장 인기를 얻고 있는 코드 포멧터인 Prettier에서 대해서 알아보겠습니다.

코딩 스타일

자바스크립트와 같이 사용자층이 넓은 범용 프로그래밍 언어의 경우, 개발자들이 선호하는 코딩 스타일이 다양해지게 됩니다.
예를 들어, 개발자 A는 문자열을 쌍따움표로 감싸줘야 한다고 주장하는 반면에, 개발자 B는 홑따옴표를 사용해야 된다고 주장합니다.
이 두 개발자가 한 팀에서 일 할 경우, 코드 리뷰 중에 이러한 사소한 코딩 스타일 차이로 키보드 배틀이 일어나는 걸 어렵지 않게 볼 수 있습니다.
대게 이런 코딩 스타일에 대한 논쟁은 답이 없을 분더러, 소모적인 자존심 싸움으로 번지게 되기 쉬워서 팀워크와 생산성에 나쁜 영향을 주게 됩니다.

Prettier

코드 포멧터(Code Formatter)란 개발자가 작성한 코드를 정해진 코딩 스타일을 따르도록 변환해주는 도구를 말합니다.
Prettier는 이러한 코드 포멧터 중에서도 최근에 가장 인기를 많이 얻어 거의 표준이 되고 가고 있는 자바스크립트 라이브러리 입니다.
쟁쟁한 오픈 소스 프로젝트들과 수많은 기업들이 Prettier를 정식 코드 포멧터를 채택해서 사용하고 있습니다.
(Facebook, React, Jest, Yarn, Babel, Webpack, Dropbox, Storybook, Paypal, MongoDB, Salesforce)

Prettier가 많은 개발자들에게서 급속히 사랑받게 된 이유는 기존 코드 포멧터와 달리 설정 여지가 거의 없다는 것입니다.
다시 말해서 Prettier에서 디폴트로 정해놓은 코딩 스타일에서 크게 벗어나기가 어렵다는 얘기입니다.
이 말은 일단 Prettier를 쓰기 시작하면 더 이상 코딩 스타일에 대해서 팀원 간에 왈가왈부할 여지가 없다는 것입니다.

그래서 처음에 Prettier를 접했을 때는 Prettier에서 강요하는 코딩 스타일이 불편하게 느껴질 수도 있습니다.
하지만 Prettier에서 정해놓은 코딩 스타일들은 오랜시간 개발자 커뮤니티의 의견이 수렴되어 결정이 된 것이기 때문에 대부분 타당한 경우가 많습니다.

Prettier의 또 다른 차별점은 단순히 개발자가 작성한 코드를 수정해주는 게 아니라 구문 분석 후에 완전히 재작성을 해준다는 것입니다.
따라서 변환된 코드가 원래 코드의 동작이 정확히 일치하는 것을 항상 보장해주면 성능도 매우 뛰어납니다.

CLI 도구로 사용하기

Prettier가 어떻게 작동하는지 직관적으로 이해하기 위해서 먼저 CLI 도구를 간단히 돌려보겠습니다.

일단 index.js 파일을 하나에 포멧팅이 엉망인 자바스크립트 코드를 작성하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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>;

}

그리고 터미널에 npx prettier "index.js" 커맨드를 실행하면 위 코드가 포멧팅되어 출력이됩니다.

npxnpm 커맨드에 대한 자세한 설명은 관련 포스트를 참고 바랍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ npx prettier "index.js"
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() * 1e7)
.toString()
.replace(/\.\d+/gi, "");

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>
);
}

다음과 같이 --write 옵션으로 위 커맨드를 실행하면 index.js 파일의 내용이 포멧팅된 코드로 바로 대체됩니다.

1
$ npx prettier --write "index.js"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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() * 1e7)
.toString()
.replace(/\.\d+/gi, "");

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>
);
}

이 것이 Prettier가 동작하는 기본적인 방식입니다. Prettier에게 소스 코드를 건내주면 Prettier는 코드를 포멧팅해서 돌려줍니다.

ES Lint와 통합하기

실제 프로젝트에서는 Prettier는 단독 CLI 도구가 아닌 일반적으로 ESLint와 같은 린터(Linter)와 통합(itegration)해서 사용하는 경우가 많습니다.

먼저 자신의 자바스크립트 프로젝트에 prettier NPM 패키지를 개발 의존성으로 설치합니다.

1
$ npm i -D prettier

그 다음 ESLint와 통합을 위해서 2개의 NPM 패키지를 추가로 설치합니다.

1
$ npm i -D eslint-config-prettier eslint-plugin-prettier

마지막으로 해당 프로젝트의 .eslintrc.js.eslintrc.json과 같은 ESLint의 설정 파일을 열어서 다음 설정을 추가해줍니다.

1
2
3
{
"extends": ["plugin:prettier/recommended"]
}

기존에 extends 옵션에 다른 값들이 있는 경우, 기존 설정보다 우선하려면 배열 내에 맨 뒤에 위치시키야 함을 주의 바랍니다.

프로젝트에 ESLint가 셋업되어 있지 않거나, ESLint가 생소하신 분들은, 아래 포스트를 통해 먼저 ESLint를 이해하고 돌아오시면 도움이 되실 겁니다.

포멧팅 예외

Prettier로 프로젝트 전체를 포멧팅을 할 때, .prettierignore 설정 파일을 생성하면 예외 시키고 싶은 파일이나 디렉토리를 지정할 수 있습니다.
예를 들어, node_modules/ 디렉토리의 경우, 외부 라이브러리의 소스 코드가 위치하고 있기 때문에 포멧팅을 할 필요가 없습니다.
또한 package-lock.json 파일도 NPM으로 패키지를 설치할 때 자동으로 업데이트는 되는 파일이므로 구지 포멧팅을 할 이유가 없습니다.

  • .prettierignore
1
2
node_modules/
package-lock.json

이렇게 두 줄을 .prettierignore 설정 파일에 추가하면 Prettier는 포멧팅할 때 지정된 디렉토리와 파일을 무시하게 됩니다.

코드 편집기

대부분의 코드 편집기에서는 Prettier를 플러그인 또는 익스텐션 형태로 제공해주고 있습니다.
그래서 사실 위에서 다루었던 것 처럼 매번 터미널에 커맨드를 날려 코드 포멧팅을 할 일은 거의 없습니다.

본인이 사용하는 편집기에서 제공하는 Prettier 플러그인을 찾아서 설치만 해주시면 됩니다.

이러한 플러그인/익스텐션을 활용하면 Prettier를 실행하기 전에 편집기 내에서 피드백을 받을 수 있기 때문에 매우 편리합니다.

마치면서

이상으로 자바스크립트 코드 포멧터인 Prettier를 어떻게 사용하는지에 대해서 알아보았습니다.
Prettier를 잘 활용하셔서 여러 명의 개발자가 하나의 프로젝트에서 일관적인 코딩 스타일을 유지하셨으면 좋겠습니다.

공유하기