
Week 2. 프론트엔드 팀 프로젝트
2주차:21 / 10 / 18 - 21 / 10 / 24 (일)
10 / 18 - 10 / 19: 프로젝트 기본 세팅 및 깃허브, 깃 익히기
(1) Grid System setup
(2) Prettier/Eslint setup
(3) branch 세팅: github-flow 변경해서 적용
(4) github-project 사용법 익히기
(5) 프로젝트 충돌관리
10 / 20 -: 개발 시작
(1) 우선순위 1순위부터 파트를 나눠서 기능 구현하기
(2) Open API 오류 🥲🥲🥲
(3) 제공된 API 에 추가 기능 요청
(4) 메인 이외에도 그때그때 필요한 기능들 구현
1주차에 의논했던 프로젝트 기술 스택 및 도구를 두근두근한 마음으로 세팅해보기로 했다. 나의 경우 Grid system을 적용해본 적이 있어서 mixin으로 만들어놓기로 하고 나머지 팀원분들이 prettier/eslint 설정을 진행해보기로 했다. 똑같은 파일을 받더라도 맥과 윈도우 간의 사소한 설정 차이 때문에 오류가 계속 발생해 좀처럼 해결되지가 않았고 prettier/eslint 설정을 하는 데에만 꼬박 하루가 소요되었다.

기존에는 항상 mobile-first로 진행했지만, 이번에는 web-first로 진행하기로 했다.
프로젝트 시간 상 태블릿 breakpoint는 없애고 모바일(sm) < 768px <= 데스크탑(lg) 로 반응형을 구현하기로 했다.
현재 2주차 일요일 째인데 아마 기능구현하느라 모바일 구현은 가장 낮은 우선순위가 될 것같다.

bootstrap gridsystem에 맞춰 gutter와 unit 등을 잡았다. 프로젝트 내 모든 파일에서 해당 클래스 선택자를 쓸 경우 적용되도록 만들었다.


대충 이런식...
⚠️ 여기서 한가지 문제가 발생했는데 template 내에 (html 파일) style 파일에 .container나 .row를 명시해놓지 않으면 아예 적용이 되지 않았다. 해당 grid.scss 파일은 webpack에서 전역으로 사용할 수 있도록 등록해놓아서 파일 내 style에 작성을 안해도될 줄 알았는데 내용이 비어있더라도 명시해놓아야 한다는 걸 깨달았다.
똑같은 boilerplate를 clone해와도 mac에서는 잘 작동하고 window에서는 계속 오류가 생겼다. 진짜 세세하게 많은 오류가 발생했는데 기억이 나는 것만 정리해본다.
1. eslintrc.json 👉🏻 eslintrc.js
2. prettierrc 파일 삭제 후 eslintrc 파일안에 prettier rules 정의
어느 누가 받더라도 npm i 를 했을 때 오류없이 무사히 작동하는 게 목표였다. 내 프로젝트에서는 prettier가 global로 깔려있어서 프로젝트 내에 prettier 패키지가 없더라도 prettierrc 파일만 있으면 잘 작동했는데 global이 아닌 프로젝트 내의 패키지를 설치해 관리하는 게 개발자나 리뷰하는 입장에서도 좋다고 팀원들과 의견을 나눴다.
3. settings.json 설정 변경

이외에도 자잘한 오류가 많이 발생했는데 기록하지 않아서 기억이 나지 않는다. 🥲
여러가지 시도를 하는 과정에서 많이 배웠지만 시간도 많이 잡아먹기 때문에 다음 프로젝트 때에는 window에서 잘 작동하는 boilerplate를 가져오면 일처리가 빨라질 것 같다. 우리는 애초에 window에서 만든 boilerplate도 prettier 오류가 생겼었기 때문에 mac에서 잘 작동하는 걸로 가져온 경우였지만 이번 경험을 토대로 window를 우선시하자...!
(어차피 맥에서는 잘 작동하기 때문에 ㅋㅋㅋㅋ...)
gitflow 전략은 브랜치가 여러갈래로 나뉘기 때문에 장기 프로젝트에 좋고, github-flow가 branch 갈래가 적기 때문에 현 프로젝트에 적절하다 판단했다. 우리는 main > dev > feature 브랜치로 나눠 feature/기능단위로 branch를 파고 PR을 날려 자체 리뷰 or 팀원의 간단리뷰를 토대로 dev로 머지하기로 했다.
notion을 기본 협업도구로 정하되 todo나 progress 등의 흐름은 github-project를 사용하면 정말 좋겠다 생각했다. github-project는 여러 형태로 관리할 수 있지만 기본적으로 칸반 보드도 제공한다!! 이건 정말 편한 점이 할 일을 issue에 등록하고 project와 연결하면 자동으로 칸반보드에 To do에 등록된다 👍👍👍

이제 열심히 기능을 구현하고 PR을 날리고 Closes 키워드 등을 통해 issue를 연결하면 팀원들이 리뷰를 간단히 해준다. 리뷰 후 머지되면 issue가 자동으로 close되고 칸반보드의 Done으로 카드가 옮겨진다. 진짜 혁신 🙆♀️🙇♀️🙆♀️🙇♀️

옛날부터 이런 거 엄청 해보고 싶었는데 드디어 소원 풀었다 ㅎㅎㅎㅎ 뭔가 드디어 협업다운 협업을 하는구나라는 생각이 들었다. 나도 이제 개발자? 풉 킥
예전에는 conflict라는 단어가 보이면 등줄기에 식은땀이 나고 뭔가 섞여서 이리저리 망할 것 같은 생각이 들었었다. 어찌어찌 하다보면 해결이 되어서 신기했지만 뭔가 본격적으로 충돌을 미리 경험하고 merge까지 완료해보자! 라는 식의 당돌한 진행은 처음이어서 그런지 몰라도 의외로 간단하고 무섭지 않은 녀석이었다. 그냥 뭐랄까...깃이 알려주는 대로 진행하다보면 간단히 해결이 된다

열심히 기능구현을 하고 PR을 날렸을 때 충돌이 나면 이 부분에서 너 충돌났어~! 라고 알려준다. 그럼 이 친구가 알려주는 대로 command 라인에서 충돌을 해결할 건지 web에서 해결할 건지 물어본다. 어차피 web 에서 해결하면 변경사항을 로컬에 또 반영해줘야 하기 때문에 command line으로 해결해보자.
이때부터는 이 친구가 하라는 대로 하나씩 클릭해가며 비교하면 된다.
(1) dev 브랜치로 가서 git fetch를 한다
(2) 다시 충돌난 브랜치로 가서 git merge origin/dev를 한다.
⚠️ 충돌이 났으니 충돌난 파일 이름이 빨갛게 변한다!
(3) 충돌난 파일로 가서 <<<<<<<<<<< 위에 있는 작은 글씨들을 하나씩 눌러보며 비교한다.

(4) 깔끔하게 merge를 한다 👏👏👏👏
👉🏻 회고: 실제로 프로젝트를 시작하고 merge 시도를 할 때마다 엄청나게 자주 충돌이 발생했지만 무섭지 않았다!!! 미리미리 충돌 연습을 해보고 팀원들끼리 모여서 차근차근 흐름을 이해한 덕분인 것 같다.

라고는 했지만 OpenAPI의 값을 기존 API에 넣어주는 어려운 작업이 먼저 해결이 돼야 하기 때문에 1, 2, 3 번은 약간 보류상태가 되었다. 기존 API가 로그인된 사용자 Token이 필요해서 로그인, 회원가입 먼저 진행이 되었다.
주영 - 로그인 페이지
지영 - 회원가입 페이지
영후 - Open API를 받아와 store에 저장
👉🏻 회고: 처음 시작할 때 유저가 많이 사용하는 1. 글 리스트 페이지 2. 글 내용(상세) 페이지, 3. 활동 관리 페이지를 먼저 만들기로 했지만 API가 먼저 사용되는 페이지를 가장 최우선으로 둬야한다는 교훈을 얻었다. 1, 2, 3 페이지는 단순 데이터를 불러와 적용하는 페이지지만 실제 중요한 건 데이터를 만들고 서버(API)에 전달하는 페이지라 생각된다. 가장 중요한 건 기획단계에서 API 검토를 철저히 하고 API 조작하는 부분을 기준으로 우선순위를 높게 분배하는 것!!
우리 프로젝트는 여행 모임 서비스 📆이다.
루트의 App 파일이 created되면 Open API 응답 결과(시 정보)를 받아와 store에 cityList에 저장한다.
Open API로 시 - 군구 정보까지만 받아올 수 있기 때문에 검색창에서도 시 - 군구 정보만 검색하도록 한다.
사용자가 검색창에 시 군구 정보를 검색하면 store의 cityList에서 사용자가 검색한 시 정보를 찾고 해당 시 code를 통해 군구 정보를 다시 불러와 store에 저장한다.
사용자가 검색한 결과를 store에 저장한다.

데이터의 흐름은 이렇게 되면 좋겠다고 의논했지만 엄청 logical하게 코드를 작성해서 필요한 사람이 store에서 가져올 수 있도록 만들어주셨다. 👍
내가 만든 회원가입 페이지에서 응답 결과로 사용자 토큰을 받으면 주영님이 로그인 관련 처리를 구현하셨다. 기존에는 fetch로 데이터를 받아왔는데 node.js 환경에선 fetch를 사용할 수 없기 때문에(?) axios로 통일하기로 했다. 이 과정에서 주영님이 instance와 interceptor를 활용해 헤더에 토큰 정보를 넣어주는 처리를 추가로 해주셨다. 로그인이 되었는지 확인하려면 주영님이 store에 만든 getter를 가져오기만 하면 된다 👏👏👏👏
추가적으로 브라우저의 쿠키에 토큰과 username을 저장해 새로고침해도 로그인이 풀리지 않도록 추가 구현하셨다.
(내 코드가 아닌 부분을 올려도 되는지 모르겠어서 글로만 열심히 작성 ㅋㅋㅋㅋㅋ 🙇♀️)
나는 이와중에 뭘했냐면 vee-validate 패키지로 회원가입 validation 처리를 했다. 내가 구현한 부분이라 열심히 얘기할 수 있는데 vee-validate 공식 문서를 통해 열심히 읽어가며 적용을 해보았다. 블로그에 vue3 프로젝트에 vee-validate를 적용한 글이 많지 않아서 의외로 헷갈렸다 (?)
아래 이미지와 같이 defineRule로 프로젝트의 main.js에 전역등록을 해 놓으면 어디서든 validator를 사용할 수 있다.

FormValidator 함수를 만들어 main.js에 불러온다.

사용할 컴포넌트 파일 내부에선 Field, Form, ErrorMessage 를 컴포넌트로 등록한다.

각각의 컴포넌트들은 form 태그, input 태그를 대신한다. validation이 맞지 않을 경우 ErrorMessage 컴포넌트를 통해 등록한 에러메세지를 보여줄 수 있다.

⚠️ ErrorMessage 컴포넌트는 기존에는 보이지 않다가 validation을 충족하지 않을 경우만 나타나기 때문에 (v-if 처럼) wrapper 태그로 감싸서 화면이 껄떡대는 것을 방지해주는 것이 좋다.

사진에서 확인가능한 것처럼 validation이 뜨지 않아도 ErrorMessage 부분에 공간이 있다.
로지컬한 데이터 흐름이 짜졌지만 아쉽게도 Open API를 사용한 첫째날 이후부터 Limited request 오류로 며칠 간 사용하지 못했다. 이는 짧은 프로젝트 기간동안 굉장히 큰 손해였고 주말이 지나 전화를 통해 일일 트래픽 1000건이 reset되지 않았다는 답변을 들었다. 전화 통화 후 일일 트래픽을 reset 시켜주셨지만 똑같은 오류가 발생할 경우 프로젝트 진행히 힘들어지기 때문에 애초에 채널에 Open API 정보를 다 저장해버리는 방법을 택했다.

Open API 오류가 발생하기도 하고 데이터를 넘겨 받아야 진행할 수 있는 페이지들도 있어서 메인 구현 외에도 그때그때 필요한 기능들을 만들었다.
프로젝트 내에서 공통적으로 사용할 컴포넌트들을 팀원들이 자체적으로 components/designs 에 넣어두었다.


원래는 props에 type이나 default 값을 지정하는 로직을 짰는데 scss에 정의해놓은 변수들을 가져올 수 없는 문제가 발생했고 멘토님께 도움요청을 드렸다. 멘토님께서는 style과 js의 역할을 확실히 구분해서 사용하는 게 개인적으로는 좋다고 추천해주셔서, props는 배열형태로 받고 default style은 scss 부분에 선언하기로 했다.
근데 공통 컴포넌트들을 만들다보니 props로 type을 받는 게 validation 처리에 좋다고 생각이 들었고 Tag 컴포넌트를 리팩토링하는 김에 로직을 좀 바꿔보았다. 기존 배열 형태로 받아오던 props를 객체 형태로 받아 type, default를 받도록 바꾸었고 어차피 default값 받는 김에 다시 스타일을 js 안에 넣기로 했다 ㅜ 이렇게 되면 scss 변수들을 넣지 못하지만 한눈에 보기 좋은 것 같다.
다만 뭐가 더 실무적으로 쓰이고 좋은 코드인지는 아직 판단이 안선다

등등



axios interceptors는 서버에 request, response 하기 전에 필요한 로직을 추가할 수 있다. 덕분에 axis instance를 사용하는 부분에선 엄청 간결하게 함수를 작성할 수 있다는 장점이 있다.

login 확인이나 user 확인은 프로젝트 이곳저곳에서 사용되기 때문에 꼭 필요한 부분인데 store를 통해 깔끔하게 정리되었다.

협업을 할 때에 가장 중요한 것은 팀원과 자유롭게 소통할 수 있는 분위기를 만들도록 노력하는 것이 일순위라 생각한다. 이전에 진행했던 프로젝트는 개인프로젝트였지만 같은 팀원들과 자유롭게 소통할 수 있었던 분위기 때문에 겁먹지 않고 모르는 것은 밤새도록 질문하며 얻어가는 것도 많고 결과적으로 코드 퀄리티도 좋았다. 팀 프로젝트를 하는 목적은 사람마다 다르겠지만 기능 구현보다 협업의 방법을 배우는 것을 일순위로 두고 진행하고 싶다. 모르는 것은 바로바로 물어보고 지식을 공유하는 분위기를 형성하는 것이 중요하다.
팀원과의 효율적인 역할분배가 어렵다. 예를 들어 인과성 있는 페이지같은 경우 전 페이지가 어느정도 완성이 되어야만 해당 데이터를 받아 다음 페이지도 진행할 수 있는 경우도 있다. 이번 프로젝트에서는 이 부분을 의식하지 못하고 기획단계를 빠르게 넘어갔지만 다음에 또다른 팀프로젝트를 진행할 때에는 기획단계에서 어느정도 시현을 완성하고 가야할 것 같다.
팀원들의 눈치를 보지 말기!! 오늘의 일정량을 끝냈으나 새벽 내내 남아 불태우는 팀원을 보면 괜스리 눈치가 보인다. 각자의 페이스가 있기에 각자 페이스대로 자유로운 분위기 속에서 프로젝트를 진행하고 팀원의 책임감을 믿자!!