관심은 있었지만 쉽게 진입할 수 없었던 Next.js 프레임워크와 관련하여 좋은 기회로 현재 나온 betadocs을 (23.5.5.자로 정식 docs로 편입되었다. ㅎㅎ) 번역해보자는 스터디가 만들어져서 잽싸게 신청을 했다.
설레쟈나~~
Next.js란?
Next.js는 React 기반의 서버 사이드 렌더링 및 정적 사이트 생성을 위한 프레임워크이다.
- 사용자가 빠르게 React 애플리케이션을 구축하고 최신 웹 개발 표준을 준수하는 것이 가능하다.
- 기본적으로 서버 사이드 렌더링을 지원하며, 필요한 경우 정적 사이트 생성 기능을 사용할 수도 있다.
- 파일 시스템 기반의 라우팅과 코드 스플리팅을 지원한다.
Next.js의 가장 큰 장점 중 하나는 이미지와 CSS 파일과 같은 정적 에셋을 자동으로 최적화하여 더 빠른 페이지 로딩 속도를 제공한다는 것이다. (추후, 서술하겠지만 이 부분을 번역했다)
- 또한 Typescript와 같은 다양한 언어 및 프레임워크와의 호환성도 높다.
Next.js 13 바뀐 부분?
22년 10월에 나온 Next.js 13 버전이 여러 업데이트를 거치며 안정화되면서 많은 요소가 deprecated되었다고 한다.
더 자세한 정보는 Next.js 공식 문서에서 확인할 수 있지만 대략 바뀐 부분은 아래와 같다.
- getServerSideProps and getStaticProps에서 context.preview 프로퍼티의 사용이 deprecated 되었다. 대신 getServerSideProps와 getStaticProps에서 preview 모드를 활성화하기 위해 previewData를 사용하도록 업데이트 해주셔야 한다.
- Image 컴포넌트에서 priority prop이 deprecated 되었다. 대신 loading prop을 사용해야 한다.
- next/head 컴포넌트에서 defaultTitle prop이 deprecated 되었다. 대신 title prop을 사용한다.
- next/router 모듈에서 useRouter 대신 useRouter()를 사용해야 한다.
- next/router 모듈에서 withRouter가 deprecated 되었다. 대신 useRouter()를 사용하거나 router prop을 사용한요.
- next/link 컴포넌트에서 passHref prop이 deprecated 되었다. 이제 모든 next/link 컴포넌트는 자동으로 href prop을 자식 엘리먼트에게 전달한다.
- next/dynamic 함수에서 ssr prop이 deprecated 되었다. 대신 ssr: false를 설정해야 한다.
번역 프로젝트 작업하기
간단하게 작업 단계 별로 직접 경험해보며 기록한 부분을 정리해보았다. 미래에 '까먹을' 나를 위해 간략하게 정리한 부분이기 때문에 자세한 부분은 다른 블로그를 참고하는 것을 추천한다.
[오픈 소스 기여 과정 요약]
fork -> clone -> upstream 연결 -> branch 생성 -> 생성한 브랜치에서 작업 -> 커밋 -> 푸시 -> 풀리퀘스트
프로젝트 내용 : Next.js Beta Docs를 번역하면서 번역본을 하나의 git repository에 공동으로 모아 관리하는 형식의 프로젝트
- 비슷한 예시로 TypeScript 한글 문서 프로젝트가 있다.
1. fork & clone
번역 작업을 할 레포지토리를 fork해온다.
그 후, fork해온 레포지토리를 로컬에 clone한다.
1. 원하는 폴더로 진입하기
2. 'git clone [내 경우, SSH 주소]' 입력
3. 그 뒤 'code .'를 통해 코드 에디터로 열기
2. upstream 연결
나중에 Pull Request를 보낼 기존 레포지토리를 연결해준다.
1. 'git remote add upstream [원본 프로젝트 저장소 경로]' 입력
2. 그 후 'git remote -v'로 잘 연결되었는지 확인한다. 아래와 같이 2개의 경로가 나온다.
2-1. origin : 자동으로 등록된 내가 원본 저장소를 fork한 레포지토리
2-2. upstream : 기여하고자 하는 프로젝트의 원본 저장소 경로
3. branch 생성
내가 작업할 branch를 만들어준다. 나의 경우 Optimizing 챕터를 번역하기로 했기 때문에 그 이름 그대로 만들어 주었다.
1. 'git checkout -b optimizing'를 입력한다.
2. 'git branch'를 입력하면 아래와 같이 뜬다. * 표시는 현재 선택된 브랜치
* optimizing
main
4. 생성된 branch에서 작업
- 나의 경우 optimizing 브랜치에서 해당 챕터에 관련한 번역 작업을 진행했다.
- 내용이 방대하여 생략한다 : 관련 포스팅
5. 커밋
해당 브랜치에 커밋의 내용을 요약한 커밋 메시지와 함께 요약해서 입력한다.
1. git add [커밋할 문서]
2. git commit -m "[커밋 메시지]"
6. Push
변경 내용을 clone해온 나의 원격 레포지토리에 push 한다............................?!
BUT!!!!
여기서 내가 작업을 하고 있을 동안, 다른 기여자들이 PR을 날려 원본 레포지토리가 업데이트 되는 경우가 생길 것이다.
- 이 때 바로 PR을 날리게 되면, PR merge를 하는 사람이 내용 충돌을 해결해야 하는 수고로움이 생긴다.
- 따라서 PR을 날리기 전에, 브랜치를 최신화시킨다. (작업 기간이 길어질 경우, 매일 아침 혹은 작업을 시작할 때 브랜치 최신화를 틈틈이 시켜주는 것이 좋다.)
- (참고: fork한 저장소에 upstream의 최신 commit 가져오기 3가지 방법)
- 아래는 위의 링크에서 git CLI를 이용한 브랜치 최신화 방법에 대한 내용이다.
6-1. 브랜치 최신화 시키기
아래 그림은 열심히 번역 작업을 한 나의 commit 내역이다.
- main 브랜치에서 optimizing 브랜치로 분기가 되어 커밋이 생긴 것을 확인할 수 있다.
Push를 하기 전에 git 명령어를 이용하여 수동 Sync를 시켜줬다. merge와 rebase 두 가지 방법으로 가능하다.
6-1-1. merge
1. Fetch + Merge 각각 해주는 버전
a. 'git fetch upstream main'을 통해 원본 레포지토리의 "main" 브랜치의 업데이트된 코드를 받아온다.
** (필요하다면) 'git fetch upstream'만 하게 되면 원본 레포지토리의 모든 변경 내용을 확인할 수 있으며 필요한 브랜치를 추후 병합할 수 있다.
b. 'git checkout [내가 작업 중인 브랜치명]'을 통해 최신 코드를 적용할 내 브랜치로 checkout한다. (현재 있는 브랜치 기준으로 병합되기 때문)
c. 'git merge upstream main' #(===git merge upstream/main === git merge upstream upstream/main)
을 통해 main에서 최종 컨펌되어 업데이트된 코드를 내 작업 중인 브랜치로 병합한다.
** upstream 리모트 저장소의 main 브랜치에서 가져온 최신 변경 사항을 현재 로컬 브랜치로 병합하는 것이다.
d. 병합된 변경 사항을 커밋한다.
d. 'git push origin [내가 작업 중인 브랜치명]'을 통해 나의 원격 레포지토리 저장소도 최신화 시켜준다.
2. 간단한 버전 : Pull (Fetch + Merge)
- git pull 명령어는 git fetch와 git merge를 합친 것이다.
- git fetch는 원격 저장소의 최신 변경 사항을 가져오고, git merge는 가져온 변경 사항을 현재 브랜치에 병합한다.
a. 'git pull upstream main'을 통해 원본 레포지토리의 업데이트 내용을 Pull한다.
b. 충돌한 게 있다면 해결한다.
c. 'git push origin [내가 작업 중인 브랜치명]'을 통해 pull 해온 commit들을 push해준다.
2의 예시
a. 'git pull upstream main'을 실행하여 원본 레포지토리의 main 브랜치의 최신 업데이트를 가져온다.
- upstream의 main은 다른 팀원들의 브랜치에서 날린 PR들이 성공적으로 merge된 최신본이다.
b. 가져온 업데이트 내용 중에서 충돌이 발생한다면, 충돌을 해결한다.
- 충돌이 발생하는 경우에는 Git이 자동으로 충돌 부분을 표시해주고, 수동으로 충돌을 해결한다.
- 충돌이 없는 경우에는 이 단계를 건너뛰고 다음 단계로 진행한다.
c. 충돌을 해결한 후, 'git push origin [브랜치명]'을 실행하여 가져온 커밋들을 로컬 브랜치에서 원격 브랜치로 푸시한다.
- [로컬 브랜치]의 커밋을 해당 원격 저장소에 푸시하는 것이다.
- 예를 들어, 'git push origin optimizing'을 실행하여 로컬 optimizing의 커밋들을 'origin' 리모트 저장소의 (같은 이름으로 자동 생성되는) 'optimizing' 브랜치로 push할 수 있다.
'git push origin main' 명령어는 로컬 브랜치인 'main'의 커밋들을 'origin'이라는 원격 저장소의 'main' 브랜치로 푸시하는 것을 의미한다. 'origin'은 원격 저장소의 이름이며, 'main'은 해당 원격 저장소의 브랜치명이다.
6-1-2. rebase
(merge 1번 방법에서 b번까지는 동일하다.)
Fetch + Rebase
a. 'git fetch upstream main'을 통해 원본 레포지토리의 "main" 브랜치의 업데이트된 코드를 받아온다.
** (필요하다면) 'git fetch upstream'만 하게 되면 원본 레포지토리의 모든 변경 내용을 확인할 수 있으며 필요한 브랜치를 추후 병합할 수 있다.
b. 'git checkout [내가 작업 중인 브랜치명]'을 통해 최신 코드를 적용할 내 브랜치로 checkout한다.
# 여기서부터 달라진다.
c. 'git rebase upstream/main'을 통해 upstream 원격 저장소의 main 브랜치의 최신 변경 사항을
현재 내 브랜치의 최상위 커밋으로 가져와 로컬 브랜치를 다시 베이스로 재정렬(rebase)한다.
d. 충돌이 있으면 해결하고, 변경 사항을 스테이징 한다.
e. 'git rebase --continue'를 실행한다.
f. 최종적으로 스테이징한 변경 사항을 커밋하고 'git push -f'로 원격 레포지토리 저장소에 업데이트한다.
(-f 옵션은 원격 레포지토리의 브랜치를 덮어쓰기 위함)
- git pull은 자동으로 merge를 하는 것이지만, git pull --rebase 명령어를 사용하면 git fetch를 사용하여 원격 저장소의 변경 사항을 가져오고, (현재 브랜치의 변경 사항을 임시 저장하고 가져온 변경 사항 위에 쌓는 것이 아니라) 가져온 변경 사항 위에 현재 브랜치의 변경 사항을 적용한다. 즉, 가져온 변경 사항 위에서 작업하게 되므로 변경 이력이 깨지지 않는다.
6-2. Push 하기
# git push origin [내 브랜치 이름]
1. 'git push origin optimizing'으로 내가 작업한 브랜치의 수정내역을 나의 원격 레포지토리의 optimizing 브랜치로 push한다.
7. Pull Request
깃헙에서 PR을 날리면 된다. 끝!
[Pull Request]
이 방법은 협업 환경에서 주로 사용된다. PR을 통해 다른 사람들이 작업한 내용을 검토하고, 변경사항을 main 브랜치에 반영할지 결정할 수 있다. PR을 통해 코드 리뷰, 토의, 충돌 해결 등의 작업이 가능하며, 변경사항을 더욱 신중하게 관리할 수 있다. PR을 통해 코드의 품질을 향상시키고, 변경사항을 검토하고 통합하는 과정에서 팀원들과 의견을 공유하며 협력할 수 있다.
8. merge될 때까지 확인 & 브랜치 삭제
PR을 날린 후, 내용에 문제가 있을 경우 해당 코드에 댓글 등이 달릴 것이다.
- 문제가 생기면 해결하면 된다. (간단하지용)
- 문제가 없을 경우, PR 내용이 merge되며 close된다.
- local과 origin에서의 작업 브랜치를 삭제까지 해주면 진짜 끝!! (추후, 수정될 일이 있다면 새로운 브랜치를 만든다!)
# 이런 식으로 optimizing 브랜치를 삭제해준다.
git branch -d optimizing
git push origin optimizing
merge가 완료된 후, 컨트리뷰터 목록에 내 프로필(왼쪽에서 두 번째)이 추가된 모습을 볼 수 있다.
🟣 레포지토리 최신화를 할 때, Merge와 Rebase 중 무엇을 쓸까?
아래 레퍼런스를 보고 오길 추천!
Merge
- 2개의 브랜치를 현재 위치한 브랜치를 기준으로 병합하는 것이다.
- 즉, 두 개의 독립적인 브랜치에서 각각 작업한 내용을 합치는 방법이다.
- git merge 브랜치 이름 :: 현재 위치한 브랜치에 해당 브랜치를 가져와 merge한다.
- merge conflict가 발생하면, 직접 코드를 수정하여 충돌을 해결한다.
- 새로운 커밋을 생성 (아래 그림 참고) 하고 두 브랜치의 작업 내용을 합쳐 넣는다.
- Merge는 간단하고 브랜치 간에 작업이 많이 달라진 경우에도 적용할 수 있다.
하지만
- 브랜치를 많이 만들어서 사용하는 경우 브랜치 간의 관계를 복잡하게 만들 수 있다.
- Git 히스토리를 읽을 때 어려움이 있을 수 있다. (아래 그림 참고)
Rebase
- 현재 브랜치를 다른 브랜치의 최신 커밋으로 변경하는 방법이다.
- 변경한 내용을 커밋하지 않고도 다른 브랜치의 변경 내용을 내 브랜치에 반영할 수 있다.
- Rebase를 사용하면 충돌이 발생하더라도 fast-forward 방식의 병합이 이루어지기 때문에 Git 히스토리를 깨끗하게 유지할 수 있다.
하지만 Rebase는 작업 내용이 많이 달라진 브랜치를 합칠 때 복잡할 수 있다.
따라서 merge와 rebase는 상황에 따라 선택해야 하며, 개인적으로는 Git 히스토리를 깨끗하게 유지하는 것이 중요하다면 Rebase를 사용하는 것이 좋다. 어디까지나 팀원 혹은 회사의 방침에 따르는 것이 우선이다.
처음 브랜치 최신화를 할 때, 구글링한 대로 Rebase를 해왔는데,
갑자기 기존 브랜치에 내 브랜치가 통합되어 있어서 땀이 얼마나 뻘뻘 나던지...
git merge와 rebase에 대해 어느정도 개념이 잡힌 소중한 기회였다!
'📌 PROJECT > 2305 Next.js Documentation : 번역' 카테고리의 다른 글
[Next.js 번역 프로젝트] 최적화 > 메타데이터 (Metadata) (0) | 2023.05.06 |
---|---|
[Next.js 번역 프로젝트] 최적화 > 이미지 (Images) (0) | 2023.05.06 |
[Next.js 번역 프로젝트] 최적화 > 글꼴 (Fonts) (0) | 2023.05.06 |
[Next.js 번역 프로젝트] 최적화 > 메인 화면 (0) | 2023.05.06 |
[Next.js 베타 번역 프로젝트] 이미지 생성 (Image Generation) -> 정식 버전에서 챕터 삭제됨 (0) | 2023.05.03 |