SSAFY 공통 프로젝트 회고록 - KidWe
작성 의도
제대로된 프로젝트에 참여한 건 이번이 처음이다. 그 전 프로젝트들은 대체로 사이드로 진행하거나, 기간이 짧았었다.
그래서 이번 프로젝트에서 배우고 느낀점, 개선해야할 점 등에 대해 생각을 많이 하였고, 이를 회고록으로 남기기로 결심하였다.
프로젝트 소개
키위(KidWe)는 유치원 관리 서비스이다. 최대한 유치원 선생님들의 일을 줄여드리기 위해 간편하고 편리함을 강조하려 애쓰려 하였다. 어떤 기능이 있는지는 메인 화면으로 대체하겠다.
6명(FrontEnd 3명, BackEnd 3명)이 7주간 프로젝트에만 전념하였다.
잘한 점
다양한 기술 도입
이번 프로젝트에서 특히 FrontEnd 팀원들 모두 새로운 기술, 툴을 도입하는 것에 긍정적이었다. TypeScript 언어, 컴포넌트를 쉽게 관리할 수 있는 Storybook과 일정 관리와 이슈 관리를 위한 Jira 와 같은 다양한 툴, React, Recoil, Tailwind CSS와 같은 다양한 라이브러리, Atomic Design과 같은 디자인 방법론까지 개발의 틀을 잡는 것까지 대부분 새로운 걸 사용해보았다. 이런 다양한 것을 도입하면서도 그냥 사용하기보다는 왜 이 기술을 사용하는지, 어떤 특징이 있는지를 열심히 분석하여 사용을 하니 처음 사용하는데도 개발을 하는데 편한 부분이 많이 있었다. 이 중 몇 가지에 대해서 자세한 기록을 남겨보겠다.
1. Atomic Design
디자인의 기초 요소들을 만들고 이를 기반으로 공통 컴포넌트를 잘 정의하여 Container / Presentational 패턴의 문제을 해
결할 수 있는 디자인 방법론이다. 개발에서 컴포넌트를 atom화(원자화) 하여 재사용성을 높히는 것이 우리 팀의 목표였기 때문에 본 패턴을 도입하였다. 하지만 문제는 어디까지 원자화할 것인지, 원자들만으로도 organism(유기체)가 될 수 있는지, atom을 어디까지 커스터마이징 해줘야 할지 등 각 컴포넌트의 기준을 설립하는 것부터 얼마나 자유도를 두어야 할 지 등 막막하여 Figma에 제작해둔 페이지 디자인에서 컴포넌트를 분류하기 시작했다. 이 중 몇 가지만 예시로 들어주겠다.
버튼 컴포넌트는 더 쪼갤 수 없으며 하나의 기능만 수행하니 당연히 atom으로 만드는 것은 모두 찬성하였다. 하지만, PositiveSmallButton/ NegativeLargeButton 등과 같이 색깔, 크기 등까지 다 따로 나누어 만드는 것은 오히려 재활용성을 떨어뜨릴 것 같았다. 따라서, Button이라는 기본 컴포넌트를 만들 size는 small, large 2가지로, variant는 positive, negative 2가지로, round도 2가지, Icon 추가 가능, 버튼 클릭 시 실행되는 이벤트 핸들러 등 몇 가지의 customizing이 가능한 컴포넌트를 만들어두었다. 물론 text는 label이라는 변수로 props에 전달한다!
즉, 우리는 기능**별**로 컴포넌트를 나누기로 하였고, 디자인이 일부 달라지더라도 이 버튼의 기능은 같다고 생각하였기에 하나의 atom으로 만들었다.
그렇다면, 이 Button은 왜 따로 만들었을까? 앞서 만든 버튼은 무언가를 수락하거나 취소하는 등의 기능의 컴포넌트였다. 하지만 Dashed Button은 대부분 새로운 항목을 추가하거나 특수한 기능이 담겨져있기 때문에 다른 기능으로 보았다. 따라서 다른 atom으로 만들어서 관리하였다.
이 컴포넌트는 유저를 보여줄 때 사용하는 Item이다. 원래는 교사/원생의 정보를 보여주는 기능을 하기 때문에 원자라고 생각하였다. 하지만, 이 Item은 정보를 보여주기만 하지는 않았다. 출석관리에서는 거절/수락을, 전체 선택에서는 check를, 프로필에서는 상세 정보를 더 볼 수 있게 Bracket 등 여러 가지 기능이 들어가있다. 따라서, 이는 molecule(분자)로 분류하기로 하였다.
다음은 Header 에 사용하는 컴포넌트이다. 겉보기에는 분자와 다를 게 없었지만, 페이지에서 Header의 역할을 하고 있기 때문에 유기체로 분류하였다.
이런 식으로 각 컴포넌트를 보며 atom, molecule, organism 중 어떤 것으로 분류할 것인지 같이 이야기 하다보니 팀원들의 디자인 기준이 동일해진 것 같아 본인이 사용하는 컴포넌트를 각자 분류하기로 하였다. 그렇게 하니 다른 팀원이 만든 컴포넌트를 재사용하려고 할 때도 무엇으로 분류되었는지 알기 쉬워 매우 편리하였다.
2. StoryBook
UI 컴포넌트를 독립적인 환경에서 그리는 툴이다. 미리보기를 작성하여 결과물을 즉시 확인할 수 있다는 장점이 있다. 이전 프로젝트에서는 페이지에서 UI 컴포넌트를 하나하나 수정하다보니 보기도 불편하고, 신경써야할 것이 많았었다.
하지만, 이를 도입하려고 할 때 망설였던 점이 있었다. 컨설턴트님, 실습 코치님들에게 storybook에 대해서 물어보았지만 대부분은 잘 모르셨었다. 그래서 사용하기를 망설였지만, 컴포넌트 설계의 결함을 미리 파악할 수 있는 등의 장점이 매우 크다고 생각하여 도입하였다.
Button 컴포넌트로 예시를 들겠다. 기존 방식대로라면 코드에서 직접 수정을 하며 변화를 보아야 했지만, storybook에서는 그 변화를 바로바로 볼 수 있어 atomic design에서 커스터마이징의 정도를 설정하는데 매우 편리하였다.
3. Recoil
상태 관리 라이브러리에 대해서는 한 번 공부한 적이 있었다. 사실 프로젝트 중반까지는 props로 데이터를 넘기면 될 정도로 깊이가 깊지 않았었다. 하지만, 개발을 진행할 수록 페이지가 넘어갈 때마다 직접 데이터를 props로 넘기다 보니 점점 코드가 복잡해지고 관리가 어려워졌다. 특히 회원가입을 진행할 때 개인정보를 props로 넘기는 것은 보안적으로 문제가 될 것이라고 생각했었다. 그래서 상태 관리 라이브러리를 도입하기로 결정하였다.
내가 맡았던 기능은 회원 가입이다. 우리의 서비스와는 결이 맞지 않는 것 같아 소셜 로그인은 도입하지 않았다. (
구현해본 적은 없지만 다들 어렵지 않게 할 수 있는 기능이라더라
)
우리의 회원 가입 플로우는 다음과 같다.
1. 역할 선택
2. 개인 정보 입력
3. 유치원 관련
3.1. (원장님) 유치원 등록
3.2. (선생님,학부모) 유치원 검색
4. (학부모) 아이 정보 등록
인지라 데이터를 props로 넘기기에는 depth가 너무 깊어지는 문제가 있었다. Recoil은 다음과 같은 형태로 선언하고, 사용하였다.
// recoil/atoms/signup/Signup.ts
import {atom} from 'recoil';
import {SignupFormState} from '@/types/signup/SignupFormState';
export const Signup = atom<SignupFormState>({
key: 'Signup',
default: {
dto: {
name: '',
tel: '',
email: '',
password: '',
role: '',
},
picture: '',
},
});
import {Signup} from '@/recoil/atoms/signup/Signup';
const [signuprole, setSignupRole] = useRecoilState(Signup);
이후 다음 버튼을 누르면 데이터를 업데이트하였다. 그러면 Signup Recoil에 업데이트된 정보가 남게 되어 여러 페이지를 넘어가도 데이터를 넘기기 편리했다.
4. 외부 Kakao 주소 API 사용
Kakao API를 사용하여 주소를 검색하고, 그 주소의 우편 번호를 받아오는 기능을 구현하였다.
외부 API를 사용하는 지라 어렵지 않을 거라 생각했는데, 생각보다 여러 군데에서 문제가 생겼다.
a. javascript -> typescript 로 변경 중 생기는 타입 에러
외부 객체는 타입을 알 수 없어 interface로 선언해주었다. 그 때 window에 daum 객체가 있다고 명시해 주는 과정에서 특정 type을 지정하라는 에러가 계속 발생하였다. @ts-ignore
를 사용하면 타입 검사를 무시할 수 있지만, 안전하지 않은 방법이라 사용하지 않았다. 또한, daum 객체가 매우 복잡한 형태로 되어있어 다른 type을 지정하지 않고 any로 결국 두기로 결정하였다.
b. 외부 스크립의 동적 로드
React Component 안에 HTML 태그를 바로 넣었더니 에러가 발생하였다. 이유는 script의 위치 때문이였다. 이를 위해서 useEffect 훅을 사용하여 script 변수에 새로 선언하여 외부 스크립트를 동적으로 로드하니 해결되었다.
c. modal의 data를 업데이트
주소 검색을 modal로 하여 이를 페이지에 다시 띄워줘야 하는데, 기존 javascript 코드는 DOM에 접근을 하여 우리의 코딩 컨벤션과는 조금 달랐다. 이 때 data를 넘기는것은 useState 훅을 사용하여 데이터를 업데이트해주었다.
팀원 간 학습 공유
팀원 모두가 이번에 새로운 기술들을 많이 도입하려다 보니 개인적으로 공부를 한 것이 많았다. 앞서 언급한 것 뿐만 아니라 PWA, React Query, MongoDB, JPA 등 각자 공부하고 정리한 것들을 노션에 같이 정리해두었다. 그러니 나의 파트가 아닌 내용도 알 수 있어 프로젝트의 전반적인 흐름을 이해하기 좋았다.
UCC 제작
UCC의 전반적인 것을 책임지고 제작하였다. 촬영과 첨부 자료 제작은 팀원들과 같이 진행하였지만, 아이디어 기획, 출연, 편집 등은 도맡아서 진행하였다. 사실 예전부터 UCC를 만들고 싶다는 생각은 하였지만, 마땅한 동기부여가 없어서 못 했었다. 하지만, 이번 프로젝트에서는 UCC 제작이 필수라는 이야기를 듣고, 내가 하겠다고 했다. 이제 사진 편집, 영상 편집까지 다 할 수 있게 되었다!
아쉬웠던 점
일정 및 시간 관리
SSAFY에서는 JIRA 사용을 필수로 하였다. 그래서 매주 해야할 일들을 정리하고, 스토리화하고, story point를 배정하여 시간 관리 까지 할 수 있는 매우 유용한 툴이라고 생각한다. 하지만, 익숙하지 않고 나의 개발 속도를 가늠하기가 힘들어서 시간이나 일정 관리가 힘들었던 부분이 있었다. 또한, 팀원들 간에서는 프로젝트 일정 관리가 제대로 되지 않아 마지막 주에 기능을 축소하게 되었다.
이제는 나의 개발 속도도 얼추 파악할 수 있고, 프로젝트 규모도 생각할 수 있을 거라 생각하여 다음 프로젝트에서는 꼭 기획에 맞게 진행되었으면 좋겠다.
프로젝트 초반 학습 부족
새로운 언어나 프레임워크를 도입하려다 보니, React와 TypeScript 모두를 새로 공부했어야 했다. 그래서 React 강의를 구매해 수강하다보니 TypeScript에 대한 학습이 부족했었다. 그래서, TypeScript에 대해서는 제대로 활용하지 못 한 것이 아쉬웠다. 프로젝트에서 TypeScript의 기능을 쓴 것이라곤 정적 타입 시스템과 Enum 뿐이였다.
다음에는 미리 관련 내용을 학습하여 프로젝트를 준비할 것이고, TypeScript에서 데코레이터 및 네임스페이스와 같은 고급 언어 기능까지 쓸 예정이다.
FCM 기술을 도입하지 못 한 점
앞서 말한 일정 관리와도 연관이 된다. 원래는 버스 승하차 기능에서 FCM 기술을 도입하여 관련 알람을 보내고 싶었다. 하지만 버스 기능을 삭제하며, 알림 서비스의 우선순위가 낮아졌다. 그래서 마지막 주에 도입해보려 firebase의 기본 세팅만 구현하였고, Firebase 호스팅에 배포하기 전에 다른 기능들을 손 보는 것이 더 중요하다는 것을 깨달았다. API, Token과 같은 보안 시스템, 프로토콜, 네트워크 통신, 비동기 처리 등을 공부하고 이용하고 싶었지만, 도입하지 못 해 아쉬웠다. 이와 관련한 CS 지식은 개인적으로 공부할 것이다.
프론트엔드의 핵심 기능 부재
팀원이 프로젝트 발표를 준비하면서 느끼게 되었다. 백엔드에서는 MongoDB와 MySQL 로의 DB 분리 작업, barun API를 활용한 게시글 자동 생성 등 여러 가지가 있었지만, 우리는 기능적으로 내세울만한 게 없었던 것 같아 아쉬웠다. 다음 프로젝트에서는 구현해보고 싶은 기능을 명확히 할 예정이다.
감사합니다
공통 프로젝트 1등을 수상하였다!
팀원들 모두 열심히 한 덕분에 얻어낸 성과라고 생각한다. 총 7주 간의 프로젝트 기간에서 기획에만 2주를 쓰다보니 완성도 있는 결과가 나올지 걱정했었고, 프로젝트 규모를 생각하지 못 해 기획에서 볼륨을 너무 크게 가져갔던 것이 아쉬웠지만, 모두가 열심히 프로젝트에 전념한 것이 프로젝트의 완성도로 나온 것 같다. 특히 마지막 주와 발표회까지 5일의 기간동안 다들 고생을 많이 했었다.
이번 프로젝트에서는 부족한 점이 많았었는데, 팀원들이 잘 이끌어주고 이해해주어 프로젝트는 잘 마무리 된 것 같다.
다들 고생 많았어요 ^__^
혹시 저희의 서비스를 이용하고 싶으시다면 다음 링크를 참고해주세요!
(8월 29일부로 SSAFY의 서버 회수로 인해 사용이 불가합니다)