Husky를 통한 prettier 자동 포맷팅!

이지원·2022년 9월 26일
0
post-thumbnail

서론

얼마전 회사에서 한 조직의 팀장을 맡게되어서
코드 스타일, 프로젝트 구조설계, 등등 여러가지 업무를 진행하게 되었는데요,
prettier라는 라이브러를 사용하여 팀원들의 코드 포맷팅 동일하게 맞춰서 코드 스타일을 맞출 수 있었습니다.
하지만 수동으로 진행하다보니 commit을 하기전 npm run prettier --write 명령어를 치기도 귀찮고, 까먹고 커밋을 하는 경우가 빈번히 발생하는 문제점이 있었습니다..

그러던 도중
commit을 할때 자동으로 prettier까지 적용해주면 좋겠다! 생각이 들어서 husky에 관해 찾게 되었습니다.

이상 서론이 길었는데요 이제 본론으로 돌아오면,

그래서 husky가 뭐죠?

Husky는 git hooks에 따라 원하는 동작을 하게 도와주는 라이브러리입니다.
git hook은 git을 쓰다가 특정 이벤트(커밋할 때, 푸시할 때)가 벌어졌을 때 특정 스크립트가 실행되도록 도와주는 게 git hook입니다.

이제 husky와 prettier을 자동화 할 수 있게 적용해봅시다.

프리티어 설치

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

프리티어가 설치되었으면 package.json 이 있는 위치에
.prettierrc 파일을 생성해줍니다.

프리티어에 옵션 종류는 아래와같이 매우 다양한데요

{
  "arrowParens": "avoid", // 화살표 함수 괄호 사용 방식
  "bracketSpacing": false, // 객체 리터럴에서 괄호에 공백 삽입 여부 
  "endOfLine": "auto", // EoF 방식, OS별로 처리 방식이 다름 
  "htmlWhitespaceSensitivity": "css", // HTML 공백 감도 설정
  "jsxBracketSameLine": false, // JSX의 마지막 `>`를 다음 줄로 내릴지 여부 
  "jsxSingleQuote": false, // JSX에 singe 쿼테이션 사용 여부
  "printWidth": 80, //  줄 바꿈 할 폭 길이
  "proseWrap": "preserve", // markdown 텍스트의 줄바꿈 방식 (v1.8.2)
  "quoteProps": "as-needed" // 객체 속성에 쿼테이션 적용 방식
  "semi": true, // 세미콜론 사용 여부
  "singleQuote": true, // single 쿼테이션 사용 여부
  "tabWidth": 2, // 탭 너비 
  "trailingComma": "all", // 여러 줄을 사용할 때, 후행 콤마 사용 방식
  "useTabs": false, // 탭 사용 여부
  "vueIndentScriptAndStyle": true, // Vue 파일의 script와 style 태그의 들여쓰기 여부 (v1.19.0)
  "parser": '', // 사용할 parser를 지정, 자동으로 지정됨
  "filepath": '', // parser를 유추할 수 있는 파일을 지정
  "rangeStart": 0, // 포맷팅을 부분 적용할 파일의 시작 라인 지정
  "rangeEnd": Infinity, // 포맷팅 부분 적용할 파일의 끝 라인 지정,
  "requirePragma": false, // 파일 상단에 미리 정의된 주석을 작성하고 Pragma로 포맷팅 사용 여부 지정 (v1.8.0)
  "insertPragma": false, // 미리 정의된 @format marker의 사용 여부 (v1.8.0)
  "overrides": [ 
    {
      "files": "*.json",
      "options": {
        "printWidth": 200
      }
    }
  ], // 특정 파일별로 옵션을 다르게 지정함, ESLint 방식 사용
}

저는 밑에 옵션들만 추가하겠습니다.

{
  "arrowParens": "always",
  "bracketSpacing": true,
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false
}

husky 설치

npx mrm lint-staged

설치하고 나면 폴더에 .husky폴더가 생성이될텐데요.

package.json 파일도 아래와같이 변경될겁니다.

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "prepare": "husky install"
  },
  "dependencies": {
    "next": "12.3.1",
    "react": "18.2.0",
    "react-dom": "18.2.0"
  },
  "devDependencies": {
    "eslint": "8.24.0",
    "eslint-config-next": "12.3.1",
    "husky": "^8.0.1",
    "lint-staged": "^13.0.3"
  },
  "lint-staged": {
    "*.js": "eslint --cache --fix"
  }
}

scripts 명령어에
"prepare": "husky install",
"lint-staged": {
"*.js": "eslint --cache --fix"
}
아래가 자동으로 생성되는것을 볼 수 있습니다.

package.json 셋팅

이제는 package.json 셋팅을 해줄것인데
scrtips 부분에 아래와같이 적용해줍니다.
lint-staged는 git add로 커밋에 올릴 변동사항이 있는 파일들만 적용을 해주게 도와주는 아이입니다.

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "prepare": "husky install",
    "lint-staged": "lint-staged"
  },

이제는 lint-staged 설정을 해줄것인데 package.json 아래에 저렇게 설정해줍니다.
의미는 js,jsx,ts,tsx확장자로 끝나는 파일들은 prettier 옵션에 설정한대로 파일 포맷팅을 맞춰주겠다는 의미입니다.

"lint-staged": {
    "**/*.{js,jsx,ts,tsx}": [
      "prettier --write"
    ]
  }

husky 셋팅

이제 마지막단계인 husky를 작업해주면됩니다.
생성된 .husky 폴더를 열어보면

아래와같이 pre-commit파일을 볼 수 있는데요
pre-commit은 git hooks 인데요, commit 을 실행하기 전에 실행해주는 파일입니다.

해당 파일에서

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint-staged

위와 같이 작성해주면 우리가 위에서 설정한 package.json scripts에 적어놓은 명령어를 실행 시켜줍니다.

이제 커밋을 해봅시다.

결과화면


확인을 해보면 이제 커밋을 하면 터미널에 무언가 알 수 없는 명령어들이 줄줄줄 실행되는데,
저희의 포맷팅을 자동적으로 맞춰주는 작업단계입니다.

이처럼 오늘 포스팅은 husky와 prettier를 통한 자동화 포맷팅에 대해서 알아봤는데요,
이부분은 매우 유용하게 사용할 수 있습니다 esLint의 문법적용을 하고싶을때 git hooks와 연결시킬 수 도 있고,,
협업에서 메인으로 사용하는 master 브랜치에는 직접적으로 푸쉬를 못하게끔 막아둘 수 도 있구요..
다양한 방법들이 있으니. 한번쯤 적용해 보시는걸 추천드립니다.
감사합니다.

profile
안녕하세요 피드백은 언제나환영입니다.

0개의 댓글