이전 블로그에서 효율적인 협업을 위해서는 git commit을 깔끔히 관리하는 것이 중요하다고 느껴 git merge에 대해 자세히 알아보고, 상황별 적합한 merge 방법에 대해 알아보았다.
협업에서 또 가장 중요한 것이 팀원들과 정해나가는 컨벤션이라고 생각한다.
협업 과정에서는 수많은 컨벤션을 정해 나가야한다.
PR및 commit의 단위, commit 메시지 형식, PR 형식, 폴더 및 파일 구조 등 통일해야 할 것이 너무나도 많다.
디프만 프로젝트에서 채택한 협업구조를 간략하게 정리해보려고 한다.
기본적인 세팅은 Next 14(CNA)의 디폴트 세팅부터 시작한다.
ESLint
ESLint는 협업 상황에서 코드의 일관성을 유지시켜주고, 잠재적인 에러를 잡아주는 역할을 한다.
예를 들어, 사람마다 arrow function을 지향할 수도 있고, 일반 function 키워드로 함수를 생성할 수도 있다.
또한 반복문을 돌릴 때 for, forEach, map 등 여러가지 방식으로 수행할 수 있다.
이렇듯 같은 기능을 수행할 수 있지만 제각각 다른 문법을 사용한다면 코드의 일관성을 유지하기 어렵다.
이를 방지하기 위해 "코드의 규칙"을 정해놓을 수 있고, 더 나아가 잠재적인 에러 탐지하기 위해 ESLint는 협업에서 흔히 쓰인다.
pnpm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
ESLint를 적용하기 위해 위 명령어로 추가적인 패키지들을 설치해주었다.
CNA로 프로젝트를 생성하면 기본적으로 .eslintrc.json 파일이 생성되어 있다.
{
"plugins": ["react", "@typescript-eslint"],
"extends": [
"next/core-web-vitals",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module",
"project": "./tsconfig.json"
},
"rules": {
"react/react-in-jsx-scope": "off", // import React from 'react' 안해도 되게 만들어줌.
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
},
"ignorePatterns": ["**/*.cjs", "**/*.mjs", "commitlint.config.js"]
}
.eslintrc.json 파일을 위와 같이 작성해주었다.
extends 속성을 사용하면, 각 rules를 하나하나 설정해주지 않아도 된다. extends 속성에 넣어 둔 plugin들에 적용된 rules가 자동으로 적용되는 것이다.
우리 팀은 기본적인 plugin들을 설정해주었다.
rules 속성에 추가적으로 필요한 규칙이나, plugin인에 적용되어 있지만 빼고싶은 규칙을 설정할 수도 있다.
예를 들어 위와 같이 any 타입을 쓰게 되면 @typescript-eslint 플러그인에서 제공하는 no-explicit-any 규칙에 의해 빨간줄이 뜨게 된다.
이러한 방식으로 코드의 일관성을 지켜나갈 수 있다.
Prettier
prettier는 코드의 스타일을 통일시켜주는 역할을 한다.
ESLint 처럼 코드의 "구현 방식"을 일관되게 유지시켜주는 것이 아니라, 코드의 "텍스트"가 일관되게 작성되도록 도와주는 것이다.
예를 들어, '빈 줄이 두 줄 이상 되면 안됨', '스코프 내부 작성 시 두 공백 들여쓰기' 등의 스타일에 맞게 자동으로 변환시켜 준다.
pnpm i -D prettier eslint-config-prettier eslint-plugin-prettier
prettier 적용을 위해 위 명령어로 패키지들을 설치해주자.
ESLint와 prettier에 겹치는 검사가 있기 때문에 이를 방지하려면 eslint-config-prettier와 eslint-plugin-prettier도 이용해서 설정해주어야 한다.
그 후 .eslintrc.json 파일의 extends 속성에
"plugin:prettier/recommended"
를 추가해주면 된다.
그 외에 세부적인 prettier 규칙을 설정해주려면 .prettierrc 파일을 생성해주어야 한다.
{
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"useTabs": false,
"tabWidth": 2,
"printWidth": 80,
"arrowParens": "always"
}
나는 팀원들과 상의하여 위의 내용정도로 prettier 규칙을 설정해주었다.
- semi: false -> 코드의 끝에 세미콜론(;)을 사용하지 않습니다.
- singleQuote: true -> 문자열을 작은 따옴표(')로 감쌉니다.
- trailingComma: 'all' -> 객체나 배열의 마지막 요소 뒤에 항상 쉼표(,)를 추가합니다.
- useTabs: false -> 들여쓰기에 탭 대신 스페이스를 사용합니다.
- tabWidth: 2 -> 탭이나 스페이스의 폭을 2칸으로 설정합니다.
- printWidth: 80 -> 한 줄의 최대 길이를 80자로 설정합니다. 이 길이를 초과하면 줄바꿈을 합니다.
- arrowParens: 'always' -> 화살표 함수의 매개변수에 항상 괄호를 사용합니다.
Husky & Lint-Staged
프로젝트를 진행하면서 우리는 수많은 commit과 push를 수행하게 된다.
이 때, 휴먼에러로 설정한 ESLint와 Prettier가 반영되지 않은 채 push가 되는 경우가 은근히 많다.
이를 방지하기 위해 husky와 lint-staged를 도입하였다.
pnpm i -D husky@8.0.3 lint-staged
위 명령어를 통해 필요한 패키지들을 설치하자.
그 후
pnpx husky install
명령어를 입력해주면 .husky 폴더가 생성될 것이다.
npx husky add .husky/pre-commit ""
그 후 commit 이전에 수행할 로직을 선언해 주기 위해 위 명령어를 입력해주면
위처럼 pre-commit 파일이 생성된 것을 확인할 수 있다(수동 생성도 가능).
결론적으로는 pre-commit 파일을
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm run format:fix
pnpm exec lint-staged
위처럼 작성해주었다.
이제 개발자가 commit 하기 전에 husky가 pre-commit 파일을 체크하고 위 명령어를 수행시켜 준다.
format:fix는
"format:fix": "prettier --write --ignore-path .gitignore ."
위처럼 내가 package.json에 prettier을 실행하도록 적용한 script 이다.
즉 commit 전에 prettier가 적용되도록 하고, lint-staged가 작동하도록 해준 것이다.
그럼 lint-staged는 대체 뭘까??
간단히 말하면 staged된 파일들에 대해 ESLint가 잘 적용되었는지 체크해주는 도구이다.
lint-staged를 적용해주기 위해 .lintstagedrc.js 파일을 생성해주고
const path = require('path')
const buildEslintCommand = (filenames) =>
`pnpm lint --fix --file ${filenames
.map((f) => path.relative(process.cwd(), f))
.join(' --file ')}`
module.exports = {
'*.{ts,tsx}': [buildEslintCommand],
}
위와 같이 작성해주었다.
"lint": "next lint"
package.json 파일에 위 script가 있으므로 pnpm lint 명령어를 통해 lint작업을 수행할 수 있다.
즉 staged된 파일 중에서 ESLint가 적용이 안되었는데 자동으로 고쳐줄 수 있다면 고쳐주고, 안된다면 commit이 수행되지 않고 에러를 뿜어내는 것이다.
테스트를 위해 ESLint의 "사용되지 않는 변수 제거" 규칙을 지키지 않고 commit 시도를 해보았다.
위처럼 husky의 pre-commit 파일 안에서 명령어들이 실행되었고, 그 중 lint-staged 실행 과정에서 ESLint가 적용되지 않아 에러를 보여주고 commit이 실행되지 않았다.
근데 팀원들도 husky 적용 내용을 잘 받을 수 있어야 한다.
clone후 pnpm i 를 수행하면 알아서 husky가 설치되도록 해주기 위해 package.json 파일의 scripts에
{
"scripts": {
...
"postinstall": "husky install",
...
},
위와 같이 내용을 추가해주자.
commitLint
주로 협업을 시작하기 전 commit 형식을 통일시키곤 한다.
예를 들어 "feat:~ 기능 구현" 이런 식이 될 수 있다.
그런데 휴먼 에러로 인해 형식을 지키지 않은 commit이 올라갈 가능성이 있다.
commitLint를 사용하면 형식에 맞지 않는 commit을 사전에 방지할 수 있다.
pnpm i -D @commitlint/cli @commitlint/config-conventional
위 명령어를 통해 필요한 패키지들을 설치해주자.
그 후 commitlint.config.js 파일을 만든 후
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'refactor',
'revert',
'style',
'test',
'design',
],
],
},
}
위와 같이 꼭 지켜져야만 하는 commit 컨벤션을 설정해주었다.
이제 husky를 통해 commit 전 메시지 형식을 체크할 수 있게 설정해줘야 한다.
pnpm husky add .husky/commit-msg ""
위 명령어를 통해
다음과 같이 .husky 폴더 내부에 commit-msg 파일을 생성해주고
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm exec commitlint --edit "$1"
위처럼 작성해주었다.
테스트를 위해 형식이 엉망인 commit을 한번 올리려는 시도를 해보았다.
위처럼 commit이 형식에 맞지 않는다는 에러를 뿜어내고, commit 올라가지 않는 것을 확인할 수 있다!
nvmrc
.nvmrc 파일을 이용하면 node 버전을 팀원들과 쉽게 통일할 수 있다.
node 버전이 다르면 어느 버전에서는 작동되는 라이브러리가 어느 버전에서는 오류를 발생시킬 수 도 있다.
또한 각 프로젝트에 맞게 그때그때 node 버전을 쉽게 바꿀 수도 있다.
.nvmrc 파일을 생성하고 사용할 node 버전을 적어주자.
v20.9.0
나는 위와 같이 v20.9.0를 적어주었다.
참고한 블로그에 따르면 .nvmrc 파일에 사용할 버전을 적어준 뒤
nvm install
명령어를 실행하면 해당 node 버전을 읽어서 설치해주고
nvm use
명령어를 실행하면 설치한 node 버전을 바로 사용할 수 있다고 되어있다.
그런데 나는 windows 를 쓰고 있는지 몰라도 잘 되지 않았다.
각 명령어 뒤에 사용할 node 버전을 한번 더 명시만 해주면 잘 실행되었다.
즉,
nvm install 20.9.0
nvm use 20.9.0
이런식으로 실행시켜주면 잘 작동된다.
버전을 직접 입력해준다해도 각각 설치해주는 것 보다 너무너무 편한 방식이다.
이처럼 효율적인 협업을 위해 여러가지 공부를 나름 꼼꼼히 진행해보았다.
이러한 도구들을 활용한다면 예상치 못한 휴먼 에러를 방지함으로써 더욱 안정적으로 프로젝트를 진행할 수 있을 것 같다~!!
참고
https://helloinyong.tistory.com/325
ESLint, Prettier Setting, 헤매지 말고 정확히 알고 설정하자.
ESLint, Prettier 관련해서 환경 세팅을 하면 항상 어쩔 땐 잘되고, 어쩔 땐 안되고... 구글링하면 그렇게 많이 나오는 방식들을 전부 해봐도 계속 안돼서 시간을 그렇게 버릴 때가 많았던 것 같다. 그
helloinyong.tistory.com
https://youth-dev-log.vercel.app/blog/nextjs-starter#2-eslint-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0
Next.js 프로젝트 설정하기(with TS, ESLint, Prettier, Tailwind css) | <dev.log/>;
next.js로 프로젝트를 시작할때 기초 설정을 어떻게 해야하는지 알아보자.
youth-dev-log.vercel.app
Nextjs, TypeScript 프로젝트에 ESlint, Stylelint, Prettier, Husky, Lint-Staged, nvmrc 설정하기
Nextjs, TypeScript 프로젝트에 ESlint, Stylelint, Prettier, Husky, Lint-Staged, nvmrc 설정하기
metacode22.github.io
https://univdev.page/posts/nvmrc/
원활한 협업을 위한 .nvmrc
nvmrc .nvmrc 파일이란, 프로젝트 구동을 위한 Node의 버전을 기록할 수 있는 파일을 말합니다. NodeJS 프로젝트에서 타인이 만든 프로젝트를 구동할 때 버전 문제가 발생해서 실행을 못한다거나, 일부
univdev.page
'FrontEnd > React' 카테고리의 다른 글
무한 스크롤(Infinite Scroll) 도입하기 (feat: useInfiniteQuery, Virtuoso) (8) | 2024.09.03 |
---|---|
효율적인 협업을 위하여 - 1 (Feat: Git Merge) (2) | 2024.07.03 |
HTTP 캐시 다루기 (2) | 2024.06.13 |
아토믹 디자인(Atomic Design) 도입하기 (0) | 2024.05.08 |
React 렌더링 최적화에 대한 고찰 (2) | 2024.04.10 |