Git (13)

깨진알·2023년 11월 30일

Git

목록 보기
13/13

코드 리뷰

왜 코드 리뷰를 해야 하는가?

개발자들은 코드 리뷰를 통해 다른 팀원들의 코드를 검토하고 이해하게 된다. 팀원 전체가 서로의 코드에 대한 지식과 이해도를 높일 수 있다. 또한, 코드 리뷰를 통해 코드의 품질도 향상되게 된다. 코드 리뷰 문화에 속한 개발자들은 자신도 모르게 다른 사람이 자신의 코드를 볼 것을 가정하고 작성하게 된다. 이는 코드의 가독성을 향상하고, 결국 프로젝트의 전반적인 품질을 높이는 결과를 가져온다. 코드 리뷰를 진행하면 충돌이 발생할 가능성을 낮추고, 발생하더라도 손쉽게 해결할 수 있다.

팀 내에 코드 리뷰 문화 만들기

  • 정기적인 코드 리뷰 시간을 정한다. 팀원 모두가 참여할 수 있는 시간을 정해 코드 리뷰를 진행한다. 이 시간에는 서로의 코드만 리뷰하기로 정하는 것이다. Pull Request의 Code Reivew 기능을 활용하면 서로의 코드를 손쉽게 리뷰할 수 있으니, 모두가 모여서 코드를 볼 필요는 없다.

  • 서로를 존중하며 피드백한다. 코드 리뷰는 피드백을 주고받는 과정이므로, 상호 존중의 문화를 만드는 것이 중요하다. 피드백은 코드를 작성한 사람을 향하기보다는 코드를 향해야 한다. 코드에 대해서도 단순히 지적하는 방식보다는 서로의 발전을 위해 제안하는 방식으로 피드백해야 한다.

  • 받은 리뷰에 꼭 대응해야 한다. 동료들의 피드백에 동의한다면 코드에 반영한다. 만약 피득백을 반영할 수 없는 상황이라면, 어떤 이유 때문에 반영할 수 없는지 설명하는 것이 좋다. 받은 피드백에 대해 어떤 식으로든 반응이 없다면, 코드 리뷰에 동기 부여가 되지 않을 것이고, 코드 리뷰를 진행하지 않게 될 것이다.


1. GitHub의 코드 리뷰 기본 UI

동료가 Pull Request를 올리고 리뷰를 요청했다고 가정해보자. 그럼 먼저 Pull Request 페이지에 들어가서 File changed를 클릭하면 UI를 확인할 수 있다. 왼쪽 부분이 파일의 변경 사항들을 보여주는 곳이다. 중앙에 있는 내용들은 파일의 변경된 코드들을 보여준다. 빨간색은 삭제된 코드를 의미하고 녹색은 추가된 코드를 의미한다.

2. 라인 별로 코드 리뷰하기

좌측에 있는 라인 번호의 오른쪽에 마우스 커서를 올리면 커멘트를 달 수 있는 창이 나올 것이다. 여기서 다양한 커멘트를 달 수 있다. 이럴 때 사용하는 기능이 suggested change이다. 이 기능은 중앙에 파일 모양 아이콘을 클릭하면 자동으로 변경 사항을 제안할 수 있도록 GitHub에서 편의기능을 만들어 주었다. 수정하고 싶은 내용을 suggestion 아래에 작성하면 된다.

Preview를 클릭해 원래 변경하상은 어땠고, 제안한 사항은 어떤지 쉽게 볼 수 있다. 그다음 리뷰를 제출하도록 하겠다. 리뷰를 제출하는 방법에는 크게 2가지가 있다.

  • Add single comment
    이 버튼을 누르게 되면 즉시 다른 개발자들이 볼 수 있도록 커멘드 형태로 리뷰가 남게 된다.

  • Start a review
    이 버튼을 누르게 되면 작성한 커맨드가 Pending 상태가 되고 리뷰가 모두 완료되었을 때 한번에 제출할 수 있게 된다. 이 상태일 때는 다른 개발자들에게 Review가 보이지 않는다.

3. 멀티라인 코드 리뷰하기

때에 따라서 여러 줄의 코드를 수정하고 싶을 때가 있다. 이 떄 사용하는 기능이 멀티라인 커맨트 기능을 사용하면 된다. 시작하는 라인 번호의 좌측을 클릭하게 되면 노란색으로 해당 라인이 표시가 된다. 이 때, shift를 누르고 다른 라인의 좌측을 클릭하면 노락색으로 범위를 선택할 수 있게 된다. 이 상태로 노란색 라인의 우측에 커서를 올리면 이전처럼 + 버튼이 활성화되는데 이 버튼을 누르면 커맨트를 달 수 있다.

참고로 #을 쓰면 다른 Pull Request를 검색하고 언급할 수 있다. 다른 PR과 연관이 있다면 이런 식으로 리뷰를 남기는 것도 좋다.

4. 이미 본 파일은 viewed로 체크하기

파일이 한 두개일 때는 상관 없지만 많을 때는 어떤 파일을 리뷰했는지 파악하기가 어렵다. 특히 한번 리뷰하고 난 후에 수정 사항을 반영해서 다시 리뷰 요청을 날렸을 때 변경된 파일만이 아닌 모든 파일을 다시 봐야 한다면 혼란스러울 수가 있다. 이를 해결해줄 수 있는 기능이 viewed 기능이다.

viewed 체크박스를 클릭하면 파일의 변경 사항이 접히게 된다. 다음 새로운 커밋에서 해당 파일이 변경되지 않았다면 여전히 viewed 버튼이 클릭된 채로 코드가 접혀 있을 것이다. 또한 코드를 하나하나 읽고 viewed를 체크한다면 우측 하단에 파란색 바가 점점 차오를 것이다.

5. 커밋별로 리뷰하기

하나의 Pull Request가 너무 크다면 커밋을 하나의 논리 단위로 분할해서 올리면 된다고 했다. 그러나 모든 기능이나 변경이 작은 PR에 맞게 분할될 수는 없다. 이런 경우에는 커밋을 활용하여 PR을 논리적인 그룹으로 분리하는 것이 좋다. 이렇게 한다면 리뷰어는 PR의 각 부분을 이해하고 그것이 전체 코드에서 어떻게 작동하는지를 파악할 수 있다.

좌측 상단에 있는 커밋별 보기 기능을 통해 커밋 단위로 리뷰를 할 수 있다. 여기서 특정 커밋을 클릭하게 되면 해당 커밋의 변경 사항만 확인할 수 있다. prev/next 버튼을 통해 이전, 다음 커밋으로 이동할 수 있다. 시간 순서대로 커밋을 확인하면서 논리적으로 어떻게 코드가 짜여졌는지 확인할 수 있다.

물론 단 하나의 커밋이 아닌 연속된 여러개의 커밋을 확인하고 싶을 수도 있다. 멀티라인을 선택했던 것처럼 커밋들의 리스트 창에서 shift 키를 누른 채 보고 싶은 범위의 커밋을 선택하면 연속된 커밋들의 변경 사항을 한번에 확인할 수 있다.

6. 리뷰 제출하기

창의 우측 상단에 Review changes 버튼을 클릭하고, 쓰고 싶은 내용을 쓴 후 Comment, Approve, Request changes 중 하나를 선택하면 된다.

  • Comment
    Comment는 코드 리뷰 중 개선점, 의문점, 제안 등을 남기기 위해 사용된다. Comment를 통해 개선 사항을 제시하거나 의문 사항을 제기할 수 있으며, 코드 작성자는 이를 확인하고 반영할 수 있다.

  • Approve
    Approve를 통해 코드가 문제없다는 의견을 코드 작성자에게 보낼 수 있다. Branch protection rule로 Approve를 필수로 만들어 두었다면 Approve를 받지 못하면 코드 작성자는 main 브랜치에 병합하지 못할 수 있다. 이 경우가 Approve 기능이 진정한 의미에서 승인의 역할을 할 수 있다.

  • Request chagnes
    Request changes는 코드 리뷰를 통해 개션이 필요하거나 수정이 요구되는 사항이 있을 때 사용된다. 리뷰어는 코드에 문제점이나 개선 사항이 있는 경우 Request changes를 통해 수정을 요청하고 작성자에게 피드백을 전달한다. 만약 리뷰어가 Approve를 주지 않았다면 머지할 수 없기 때문에 코드 작성자는 이런 리뷰를 반영해서 새로운 커밋을 올릴 것이다. 그 때 해당 커밋을 다시 리뷰하고 적절하게 코드가 수정 됐다면 Approve를 통해 코드 머지를 승인할 수 있다.


# 좋은 커밋이란?

  • 의미 있는 단위의 작업해야 할 것

한 개의 커밋이 하나의 기능이나 작업을 완성해야 좋은 커밋이다. 작업의 크기는 작게 유지하는 것이 좋지만, 그렇다고 너무 작은 단위로 커밋하는 것은 다량의 커밋만 생성할 뿐 좋은 커밋이라고 할 수 없다.

  • 생성된 커밋은 동작이 가능한 형태여야 할 것

커밋을 생성할 때는 생성한 커밋이 정상적으로 동작하는지 검증해야 한다. 검증할 때는 개별 커밋의 동작뿐만 아니라, 프로젝트 전체의 동작을 방해하지 않는지도 함께 봐야 한다. 이런 검증 작업은 자동화하기도 하낟.

  • 커밋 메시지는 명확하고 간결하게 작성되어야 할 것

커밋 메시지는 코드 변경 사항을 빠르게 파악하는데 중요한 역할을 한다. 작업의 히스토리를 이해하는데 큰 도움을 주며, 문제가 발생했을 때 원인을 찾느데도 도움이 된다. 따라서 커밋 메시지는 그 자체로도 커밋의 의미를 명확하게 전달해야 한다. 이를 위해 Conventional Commit이라는 커밋 메시지 규칙이 생겼다.

이 규칙에서 커밋 메시지는 <type>(<scope>): <subject>의 형식을 따르게 된다. 여기서 type은 커밋의 종류, scope는 커밋이 영향을 미치는 범위, subject에는 커밋의 간략한 설명을 적는다.

다음은 자주 사용하는 type이다.

type 설명
feat 기능 개발과 관련
docs 주석/ReadME 등 문서화 관련
test 테스트 관련
fix 버그나 typo 등 수정 사항 관련
chore 코드와 관련이 없는 내용들을 수정할 때 (License 등)
ci CI/CD 등과 관련한 작업을 수행할 때

추가로 Conventional Commit을 사용할 경우 커밋 메시지의 원하는 부분을 추출해서 자동으로 문서화할 수 있다. 예를 들면 feat type을 가진 커밋 메시지를 모아서 Release Note 등을 자동으로 생성할 수 있다.

즉, Conventional Commit은 엄격한 형태의 규칙은 아니다. 꼭 규칙을 따를 필요도 없다. 이는 일종의 가이드라인과 같은 것이기 때문에 팀, 조직 등에서 편리한 방법으로 적용해서 사용하면 된다. 이러한 규칙들을 일종의 기준으로 삼고 이를 기반으로 팀 내 조직 문화를 만드는 것이 좋다.


# 자동으로 규칙 체크하기

개발자들은 자동화를 좋아한다. 규칙을 외우고 적용하는 불편함을 그냥 보고 넘길리가 없다. 이 문제점을 해결하기 위해 등장한 것이 바로 Linting이다. Linting은 소스 코드에서 스타일, 문법, 오류 등이 특정 규칙에 어긋난 것이 없는지 자동으로 체크해 주는 툴이다. 이러한 Linting 툴을 이용해 개발자들이 작성한 코드가 스타일 가이드를 위반하지 않았는지 자동으로 체크할 수 있다. 언어별로 스타일 가이드가 다르기 때문에 사용하는 언어에 따라 Linting 툴들을 맞춰 사용하면 된다.

Linting 외에도 Formatter이라는 툴도 있다. Linting 툴이 작성된 코드의 규칙 위반 여부를 검사만 한다면, Formatter는 Linting에 맞도록 자동으로 코드를 바꿔준다. Formatter를 사용하면 자동으로 스타일 가이드에 맞춰서 코드가 변경되기 때문에, 개발자들은 스타일을 고민할 필요 없이 로직에만 집중할 수 있다.

# Linting 툴을 사용하면 어떤 효과를 볼 수 있을까?

Linting은 팀 전체에서 동일한 코딩 스타일을 유지할 수 있도록 도와준다. 이는 코드 가독성을 높이고, 다른 개발자들이 코드를 이해하기 쉽게 만든다. 또한 잠재적인 버그와 오류를 사전에 발견할 수 있도록 도와준다. 코드 스타일의 일관성을 유지하면서 실수를 방지하고, 품질 좋은 코드를 작성할 수 있게 해준다. 또한 팀원들이 Linting을 사용하면 서로의 코드 리뷰 시간을 단축하는 효과도 있다. Linting 규칙을 통해 일관성 있는 코드를 작성하게 되므로, 코드 리뷰어는 스타일 가이드 준수 여부에 집중할 필요 없이 핵심 로직에만 집중할 수 있다.

# Git을 사용해 팀원간의 Linting 규칙 통일하기

Linting이 많은 부분을 자동화해 준다고 하더라도 각자 Link 규칙을 구두로 혹은 문서로 공유하는 것은 여전히 실수를 유발한다. 각 Linting 툴들은 설정 파일을 지정해서 해당 설정 파일로부터 자동으로 Linting이 설정되게 할 수 있다. 이러한 설정 파일을 Git을 통해 공유하면 모두가 손쉽게 Linting을 설정할 수 있다.

팁!

자바스크립트에서는 주로 ESLint와 Prettier를 사용한다. ESLint는 Linter로서, Prettier는 Formatter로서 작동한다.

  • ESLint
    ESLint는 가장 많이 사용되는 JavaScript의 Linting 도구이다. ESLint는 플러그인을 사용해 React, Vue 등과 같은 프레임워크나 라이브러리에 맞는 특화된 규칙을 추가할 수 있다.

프로젝트 루트에 .eslintrc 파일을 생성하고 ESLint 옵션을 추가할 수 있다.

{
	"root": true,
    "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
    "ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"]
}

이 설정은 현재 파일이 프로젝트의 최상위(root) 레벨에 있는 ESLint 설정 파일임을 나타내고, ESLint의 기본 규칙인 "eslint:recommended"와 TypeScript를 위한 규칙인 "plugin:@typescript-eslint/recommended"를 사용하도록 설정한다. 또한, 테스트와 생성된 파일들을 Linting에서 제외하고 있다. 다음 두 명령 중 선택해서 사용할 수 있다.

npx eslint yourfile.js
yarn run eslint yourfile.js

아래 명령어를 통해 복잡하고, 어려운 설정 내용을 읽지 않고 cli로 interactive하게 linting을 설정할 수도 있다.

npx eslint --init

  • Prettier

Prettier는 코드 포매팅에 초점을 맞춘 도구로서, JavaScript뿐만 아니라 TypeScript, CSS, HTML 등 다양한 언어를 지원한다.

프로젝트 루트 하위에 .prettierrc 파일에 Prettier 옵션을 추가할 수 있다.

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true
}
  • "trailingComma": "es5" : ES5에서 지원하는 위치에서 코드 뒤에 콤마를 추가한다.
  • "tabWidth": 2 : 탭의 너비를 2 스페이스로 설정한다.
  • "semi": true : 문장 끝에 세미콜론을 사용한다.
  • "singleQuote": true : 문자열을 표시할 때 단일 따옴표를 사용한다.

이와 같이 설정된 Prettier는 지정된 규칙에 따라 코드를 자동으로 정렬한다. 다음 두 명령 중 선택해서 사용할 수 있다.

npx prettier --write yourfile.js
yarn run prettier --write yourfile.js

주의!
ESLint와 Prettier는 서로 충돌할 수 있기 때문에 이를 방지할 수 있는 플러그인을 설치해 줘야 한다. 아래 명령을 실행하여 플러그인을 설치하면, 충돌을 방생시키는 설정을 비활성화할 수 있다.
npm install eslint-config-prettier eslint-plugin-prettier --save-dev
profile
프론트엔드 지식으로 가득찰 때까지

0개의 댓글