4주간 최종 팀프로젝트를 진행하며 겪은 일, 배운점, 역할 등에 대해 정리하고자 한다.
부트캠프에서의 마지막 프로젝트이다보니 이번엔 정말 취업을 하는데 도움이 되도록 하고 싶었다. 그래서 첫 회의때 하고 싶은 주제를 생각해오고 어떤 성과를 얻어가고 싶은지 생각해오자는 이야기를 꺼냈다.
나는 프론트엔드 개발자로 취직을 하고 싶었다. 최근 프론트엔드 채용 공고를 보다보면 공통적으로 나오는 키워드들의 집합과 평소에 내가 시도해보고 싶었던 기술들의 공통분모를 정리해봤다.
IDL
, MSA
: GraphQL, gRPC
FE
: React-Query , emotion, recoil
BE
: nest.js
in-memory
: redis
message queue
: rabbitMQ / kafka
CI/CD
: vitest/jest , github action
DevOps
: docker, kubernetes(진짜 하고싶은데 좀 비싼거같음.. 찾아봐야…)
SSR
: next.js
패키지 매니저
: yarn
모듈 번들러
: webpack
개발 문화
: 클린 코드
첫 회의때 각자 관심을 갖던 주제는 다음과 같다.
대체로 건강 관련 약을 자주 복용하다보니 약 성분 비교, 예방 관련 서비스에 가장 많은 의견이 모아졌었다. 다만 그런 전문적인 지식에 대해 잘 알지 못한다는 단점이 크게 느껴져서 그 다음으로 간병인 / 요양병원 매칭 플랫폼을 생각했다.
이 경우 정말 필요한 기능에 대해 고민을 하게 되었고 결과적으로 내가 평소에 관심있던 WebRTC 기술을 도입하여 커피챗과 같이 시니어 개발자와 상담을 할 수 있는 플랫폼이되 화상 회의 기능을 제공해주는 형태를 도출하게 되었다.
그래서 나온 주제가 WebRTC 기반 1:1 화상 컨설팅 플랫폼 : 커리업 이었다.
이번 프로젝트에서는 6인 규모였고 3인씩 백엔드 / 프론트엔드로 완전히 분할하여 프로젝트를 진행했기에 내가 속했던 프론트엔드 팀의 입장에서 회고를 작성하고자 한다.
이번 프론트엔드 멤버 3인은 모두가 figma 를 잘 다룰수 있는 인원들이었다. 그래서 이전 프로젝트처럼 내가 혼자서 디자인을 모두 하지 않아도 되는점이 좋았다.
또한 프론트엔드 팀원분들의 디자인적 시야가 좋아서 결과적으로 참고한 디자인 레퍼런스와 애니메이션 레퍼런스를 선정하게 되었고 이를 기반으로 디자인 작업을 시작했다.
기존에 React 프로젝트를 진행해왔고 사실 부트캠프에서는 next.js 를 배운적이 없다.
그럼에도 프론트엔드 채용에 있어 next.js 를 사용할수 있는지 없는지 여부가 큰 비중을 차지한다고 생각했고 SSR 을 통한 SEO 최적화같은 측면에서 모든 인원이 next.js 의 사용을 희망해서 이 기술을 사용하기로 논의했다.
그런데 이 결정으로 인해 얼만큼의 시간이 지연될지 잘 몰랐던 부분으로 인해 어느정도 시간이 지체되었던 것 같다.
next.js 입문
next.js 입문2
next.js 14 + styled component
next.js + styled component 오류 해결
생활코딩 및 Next.js docs 를 기반으로 next.js 에 대해 알아갔고 타입스크립트, 리액트, Next.js로 배우는 실전 웹 애플리케이션 개발 라는 책을 참고하며 프로젝트를 진행했다.
와.. App Router 를 사용하려 한게 문제였을까
Next.js 14 로 넘어오며 Page Router 에서 App Router 로 바뀌는 과정에서 너무 많은 부분이 바뀌었다.
참고한 책도 Next.js 13 버전이었고 심지어 공식문서에 styled component 에 대해 설명이 쓰여있던 부분도 Page Router 위주였다. ( App Router 용으로 코드가 하나 니와있긴 했지만 theme 를 적용하는 방법같은건 나와있지 않았다. )
가장 최신 버전을 사용해서 개발을 하려고 했던게 좀 성급했다는 생각이 들었다.
심지어 개발을 시작한 1주차에 사용한 storybook 버전은 4주차쯤 새 버전이 나오기도 했다.
storybook 은 docs 가 제대로 정리되어 있지 않았다. 공식 tutorial (구버전) 과 learn (최신버전) 에 나와있는 내용이 달랐다. 어떤 addon 은 어떻게 사용되는지 사용법이 소개되어 있는데 최신버전에선 deprecated 되어있는 것도 있었다.
이처럼 버전차이로 인해 혼란스러운 내용이 많았다...
팀원분중 이번에 해보고 싶은 GROUND_RULE 중에 일관화된 코딩컨벤션 규칙과 깔끔하게 정리된 README 를 원하시는 분이 있었다.
마침 최근에 우아한테크코스 프리코스를 진행하며 ESLint + Prettier 를 적용해본 적이 있기에 다음과 같이 설정하여 코딩컨벤션 규칙을 적용했다.
// eslintric.json
{
"extends": [
"next",
"next/core-web-vitals",
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:import/errors",
"plugin:import/warnings"
],
"rules": {
"react/react-in-jsx-scope": "off",
"import/order": [2, { "alphabetize": { "order": "asc" } }],
"prettier/prettier": [
"off",
{
"trailingComma": "all",
"endOfLine": "lf",
"semi": false,
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2
}
],
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"react/no-unknown-property": "off",
"react/prop-types": "off",
"import/named": 0,
"react-hooks/rules-of-hooks": "off"
},
"plugins": ["@typescript-eslint", "import"]
}
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": "src",
"plugins": [
{
"name": "next"
}
],
"allowImportingTsExtensions": true // typescript 에서 .ts, .tsx 확장자로 모듈 불러오는 것 허용, 이 옵션은 noEmit 이 true 여야 한다.
},
"include": [
"next-env.d.ts",
"src/**/*.ts",
"src/**/*.tsx",
".next/types/**/*.ts",
"recoil.ts",
"src/app/chat/page.jsx",
"src/openvidu/OvVideo.js",
"src/openvidu/registerServiceWorker.js",
"src/openvidu/UserVideoComponent.js"
],
"exclude": ["node_modules"]
}
이번 팀 프로젝트에서도 스크럼 및 스프린트 기반으로 회의를 진행했다.
매일 아침 회의전 각자 전날에 어떤 일을 했고 오늘 어떤 일을 할 것인지, 혹은 알아봤던 사항중 팀원들에게 공유하고 싶었던 사항들에 대해 회의시간때 공유하는 방식으로 회의를 진행했다.
회의를 하며 추가적으로 정리했던 사항들을 노션 홈 화면에 정리하여 편리하게 확인할 수 있도록 했다.
기본적으로 Next.js 를 사용했으니 vercel 을 통해 레포지토리만 등록해두면 너무나도 쉽게 빌드, 배포를 구현할 수 있었다. 그런데 프로젝트 초반 github actions 를 꼭 다뤄보고 싶었던 목표를 갖고 있기도 했던 터라 atomic design 패턴으로 다수의 프론트엔드 개발자와 협업을 하는 상태에서 컴포넌트의 상황에 대해 공유 및 확인이 용이하도록 하고 싶었기에 storybook 을 활용하며 chromatic 으로 storybook 을 자동 배포하는 과정에서 github actions 를 활용했다.
# Workflow name
name: 'Chromatic Deployment'
run-name: ${{ github.actor }}의 스토리북 배포
# Event for the workflow
on:
pull_request:
branches:
- main
# List of jobs
jobs:
test:
# Operating System
runs-on: ubuntu-latest
outputs:
status: ${{ job.status }}
# Job steps
steps:
- name: checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: cache dependencies
id: cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-storybook
- name: depedency install
if: steps.cache.outputs.cache-hit != 'true'
run: npm ci
- name: publish to chromatic
id: chromatic
uses: chromaui/action@v1
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: comment PR
uses: thollander/actions-comment-pull-request@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
message: '🚀storybook: ${{ steps.chromatic.outputs.storybookUrl }}'
참고로 secrets 로 접근하는 환경변수는 Security - Secrets and variables 에서 추가해줬고 GITHUB_TOKEN 같은 경우는 따로 이곳에 추가하지 않아도 된다.
PR 템플릿을 위와 같이 설정했다.
그래서 PR 할때마다 자주 실수할 만한 요소들을 넣어두고 merge 혹은 PR 시 미리 실수를 방지할 수 있도록 했다.
이슈 역시 템플릿을 생성해둬서 일관성 있는 issue, pr 을 생성할 수 있도록 했다.
자세한 사항은 깃허브 Readme 를 참고하자.
프로젝트를 진행하며 그래도 비교적 코딩 컨벤션, 이슈, PR 컨벤션 등 다수의 개발자들과 협업시 일관성 있게 개발작업을 진행할 수 있던 것 같다.
또한 프로젝트 초기 목표로 했던 성과중 next.js 활용에 익숙해지는 것, github actions 활용, WebRTC 기술 및 openvidu 오픈소스 적용 같은 목표들을 이룰 수 있어서 좋았다. 추후 jenkins 를 사용해서도 CI/CD 를 구현해보는 것과 pretier, eslint 에 Airbnb 코딩 컨벤션 적용, jest 로 컴포넌트 유닛 테스트 적용하는 것과 같은 것을 해보고 싶다..