5월부터 7월까지 2달간 팀 프로젝트를 진행하였다. 기술 및 커뮤니케이션과 관련해 더 성장하고 싶었고 개인적으로 이번 프로젝트를 통해 구현하고 싶었던 기능을 구현함으로써 FE 개발자로 다양한 경험 및 지식을 쌓고 싶었다.
👉 웹 사이트 소개
다락책방은 독서를 좋아하는 사람들을 위한 온라인 플랫폼입니다.
우리의 서비스를 통해 도서 검색과 독서 기록을 관리하고, 사용자에게 맞춤형 책장을 추천해드립니다. 또한, ChatGPT를 활용하여 사용자의 요청에 맞는 도서를 추천해드리며, 온라인 및 오프라인 도서 소모임을 운영할 수 있습니다.
👉 핵심 기능
📚 도서 검색 및 독서 기록
다락책방은 kakao 도서 데이터베이스를 활용하여 사용자가 원하는 도서를 손쉽게 검색할 수 있습니다. 검색한 도서를 개인 독서 기록에 추가하여 읽은 책을 효율적으로 관리할 수 있습니다. 독서 기록에는 독서 날짜, 책 사진, 독서기록, 감상해쉬태그 등을 포함하여 자신의 독서 경험을 기록할 수 있습니다.
👩👩👧👧 사용자별 맞춤 책장 추천
다락책방은 사용자의 독서 기록과 관심사를 분석하여 맞춤형 책장을 추천해줍니다. 추천된 책장은 사용자와 비슷한 책을 읽은 다른 사용자의 책장입니다. 따라서 사용자의 독서 취향과 관련된 다양한 도서를 포함하며, 사용자는 해당 책장을 통해 새로운 책을 발견하고 읽을 수 있습니다.
💎 ChatGPT를 활용한 사용자의 prompt에 맞는 책 추천
다락책방은 ChatGPT를 활용하여 사용자의 질문이나 요청에 따라 적합한 도서를 추천해줍니다. 사용자는 ChatGPT와 대화하며 독서 관련 정보나 특정 주제의 도서 추천을 받을 수 있습니다. 이를 통해 사용자는 편리하게 도서를 찾아갈 수 있습니다.
👨🏫 온, 오프라인 도서 소모임 운영
다락책방은 독서를 즐기는 사람들을 위한 온라인 및 오프라인 도서 소모임을 운영합니다. 온라인 도서 소모임에서는 독서 관련 토론, 작가와의 만남, 독서 이벤트 등 다양한 활동을 즐길 수 있습니다. 또한, 오프라인 도서 소모임에서는 현실에서 사람들과 함께 독서를 즐길 수 있는 기회를 제공합니다. 독서 소모임을 통해 새로운 친구들을 만나고 독서에 대한 다양한 경험을 공유할 수 있습니다.
기획서 작성, 팀문화 설정, 기능 명세서 작성, 스프린트 주기 설정 및 회고 작업과 관련해 서로 의견을 주고 받고 결정된 사항은 노션페이지에 정리해두었다.
작업 전에 FE 팀원끼리 목표, 도전, 기술, 초기 세팅, 폴더 구조, 파일 및 type명, 코어타임 등과 관련해 미리 설정해두면 좋을 것 같다는 생각이 들어 팀원들에게 제안을 했다. 팀원들에게 몇일 간 고민하는 시간 후 설정하는 것이 어떠냐는 의견을 전달했고 팀원들이 수락 후 몇일 뒤에 회의를 통해 위의 사항들을 결정했다.
기획서 및 기능 명세서를 토대로 디자이너 분에게 전달할 디자인 프로토타입을 피그마를 통해 제작했다. 서로 의견을 공유하며 부족한 부분을 보완하는 시간을 가졌다.
👉 담당 역할
스프린트 한개의 주기를 2주로 잡았고 기능명세서를 토대로 스프린트 마지막날에 다음 스프린트에 진행 할 작업을 각자가 선택했다. 필자는 초기세팅 및 배포, git action을 통한 배포전 lint 및 type check, 소셜 로그인 구현, 공통 컴포넌트 구현, 도서 검색 페이지, 독서 모임 조회, 생성, 수정 페이지, GA 도입 등의 작업을 진행했다.
🔎 각 기능을 담당한 이유
초기세팅 및 배포, git action을 통한 배포전 lint 및 type check
프로젝트의 전체적인 흐름을 파악하고 그로인해 팀원 전체와의 원할한 커뮤니케이션을 하고 싶어 담당하게되었다.
소셜 로그인 구현
유저와 관련된 작업은 여러 변수사항이 많고 프로젝트 전체에 영향을 줄 수 있는 영역이다. 그렇기 때문에 많은 error가 발생하고 추가로 진행할 작업이 많을 것이라 판단했다. error 해결 및 사용자 입장에서 작업을 진행하다보면 사용자 입장에서 개발하는 능력이 향상 될 것이라 판단해 작업을 진행했다.
공통 컴포넌트 구현
재 사용성 및 독립성 있는 컴포넌트를 개발하고 싶어 담당하게 되었다.
GA 도입
웹 사이트의 방문자 수 및 이탈률을 check 하는 것이 사용자 입장에서 개발하는 것에 있어 큰 동기부여가 될 것이라 생각했다. 더불어 직접적인 피드백을 통해 부족한 점을 개선할 수 있도록 하는 척도라 생각을 해 GA를 도입했다.
담당 페이지
TanStack Query의 useInfiniteQuery Hook 및 option 들을 좀더 deep하게 학습함으로써 TanStack Query 라이브러리를 좀 더 능숙하게 사용하고 싶어 무한 스크롤 기능 및 여러 option이 필요한 해당 페이지를 담당하게되었다.
개발일지 작성을 통해 오늘 진행할 작업량을 예상할 수 있었으며 배운점 및 어려웠던 점 등을 기록하며 어제보다 내가 성장하였는지 check 할 수 있었다.
슬랙을 통해 의견을 제안하거나 궁금한 것이 있을 때 팀원들과 함께 의논하며 새로운 것을 배우거나 부족한 부분을 보완할 수 있었다.
GitHub를 통해 1명 이상이 코드 리뷰를 하면 main에 merge 되도록 규칙을 설정했으며 리뷰를 통해 코드의 가독성 및 적절한 위치에 코드가 작성되었는지와 관련해 수정할 수 있었다. 더불어 다른 팀원이 새로운 개념 도입 시 도입 이유 및 장단점을 공유함으로써 소스코드와 관련해 deep하게 이야기 할 수 있었다.
디스코드를 통해 일주일 2~3번 데일리 스크럼, 1번 스프린트 회고를 진행하면서 각 분야간 전달 사항을 전달하거나 각자가 진행한 작업을 서로 피드백하며 부족한 부분을 보완할 수 있었다.
노션을 통해 회의 내용 및 문서화가 필요한 부분을 정리함으로써 팀원 및 프로젝트 진행 상황을 보다 쉽게 파악할 수 있었다.
피그마를 통해 디자이너님이 제작해주신 디자인을 적용하고 프론트엔드와 디자이너간 커뮤니케이션을 통해 UI 관련해 서로 의견을 내며 부족한 부분을 보완 했다.
도서 검색페이지 제작을 통해 useInfiniteQuery 학습 및 많은 error를 만나고 해결하며 조금 더 성장한 것 같다!
👉 도서 검색 페이지 소스코드
import dynamic from 'next/dynamic';
import { useEffect } from 'react';
import { useRecoilState } from 'recoil';
import tw from 'tailwind-styled-components';
import BottomNav from '@/components/common/BottomNav';
import Header from '@/components/common/Header';
import SearchInput from '@/components/common/SearchInput';
import Seo from '@/components/common/Seo';
import useRememberScroll from '@/hooks/useRememberScroll';
import { searchBookTitleAtom } from '@/recoil/book';
const InfinityScrollLists = dynamic(
() => import('@/components/book/search/InfinityScrollLists'),
);
const BookSearchPage = () => {
const [searchBookTitle, setSearchBookTitle] =
useRecoilState(searchBookTitleAtom);
const { currentScroll, resetScroll } = useRememberScroll('bookSearch');
const onSubmit = (keyword: string) => {
setSearchBookTitle(keyword);
};
useEffect(() => {
if (currentScroll === 0) return;
window.scrollTo(0, Number(currentScroll));
resetScroll();
}, []);
return (
<>
<Seo
title='다락책방 | 도서 검색'
description='책을 검색할 수 있는 공간'
/>
<Container>
<BackGroundWrap>
<HeaderStyle />
<BackGround>
<Title>
어떤 책을 <br />
찾고 계신가요?
</Title>
<SearchInputWrap>
<SearchInput onSubmit={onSubmit} inputText={searchBookTitle} />
</SearchInputWrap>
</BackGround>
</BackGroundWrap>
<BookSearchListsWrap>
<BookSearchLists>
<InfinityScrollLists searchKeyword={searchBookTitle} />
</BookSearchLists>
</BookSearchListsWrap>
</Container>
<BottomNav />
</>
);
};
export default BookSearchPage;
const Container = tw.div`
bg-white
h-screen
`;
const BackGroundWrap = tw.div`
fixed
top-0
left-[50%]
translate-x-[-50%]
max-w-xl
w-full
h-[18.75rem]
bg-white
`;
const HeaderStyle = tw(Header)`
absolute
top-12
z-10
`;
const BackGround = tw.div`
w-full
h-[18.75rem]
relative
`;
const Title = tw.h1`
absolute
left-5
bottom-20
text-clamp3xl
leading-normal
`;
const SearchInputWrap = tw.div`
absolute
w-[90%]
left-5
bottom-2
mx-auto
`;
const BookSearchListsWrap = tw.main`
pt-[19.5rem]
pb-24
bg-white
`;
const BookSearchLists = tw.div`
w-[90%]
mx-auto
`;
👉 그 외 소스코드
개발을 통해 기능을 구현하는 것도 중요하지만 작업을 진행한 이유, 작업을 진행함에 있어 특정 기술을 선택한 이유 등을 고려하는 것도 중요하다고 생각한다. 블로그를 통해 개발시에 생각하지 못했던 부분을 보완하고 지식의 정확성을 확고하게 하고 싶어 블로그 포스팅을 했다.
Next.js 프로젝트 초기 세팅(CNA 부터 폴더 생성까지, With TS)
Next.js 프로젝트 Vercel로 배포 및 CI/CD 구축
Next.js + TS 프로젝트에 Google Analytics 이식하기
useInfiniteQuery로 무한 스크롤 구현하기(feat. TanStack Query)
Infinity Scroll 리스트 아이템 데이터 수정 안되는 문제(Feat. useInfiniteQuery, fetchNextPage, hasNextPage)
👉 로그인 기능
👉 도서 검색 기능
👉 다락책방 방문하기
프로젝트를 진행하며 아쉬웠던 점을 통해 배우고 다음에는 더 좋은 프로젝트를 진행하게 위해 아쉬웠던 점을 기록해두는게 좋다고 생각했다. 시간을 내서 리팩토링을 진행해야 할 것 같다!
- 디자인 사항이 수정됨에 따라 미리 제작한 공통 컴포넌트가 필요없어진 점
- CSS 및 TS와 관련해 deep한 고민을 하지 않고 사용했던 점
- 무한스크롤 + SSR을 통해 data pre-fetch 못한 점
- 스켈레톤 적용을 통해 UX를 향상시키지 못한 점
- 이미지 최적화를 통해 성능 최적화 작업을 해봤는데 담당 페이지에 이미지 개수가 적어 큰 성과를 보지 못한 점
- 사용자 입력 폼 관련 error 처리를 하지 못해 여러 상황에 대처하지 못한 점
- auth 관련 axiosinstance와 그 외 인스턴스를 생성해 인스턴스의 역할을 분리하지 못한점
- 다들 스케줄이 맞지 않아 코어타임 참석률이 저조해 비동기 커뮤니케이션이 많았던 점
- 각자 담당한 기능에 시간을 할애하다보니 deep한 코드리뷰가 이뤄지지 못한 점
이전 프로젝트를 진행할 때보다 많은 영역에 있어 성장을 한 것 같다. 여러 기능 구현 도전, 사용자 입장에서 최적화 작업, 가독성 좋은 코드 작성 등을 통해 여러 경험을 할 수 있었으며 내가 성장한 부분과 더불어 부족한 점을 인지할 수 있었다.
- 사용자 입장에서 웹 사이트를 이용해보며 최적화를 하는 것이 UX 향상의 기본이라는 것을 배웠다.(페이지 속도 개선, SEO, GA 도입 등등)
- 디자이너와의 원활한 커뮤니케이션이 사용자에게 높은 퀄리티의 UI를 제공할 수 있고 프론트 및 백엔드 간의 원활한 커뮤니케이션이 UX향상과 안정적인 웹 사이트를 제작할 수 있다는 사실을 인지 할 수 있었다.
- 팀원들이 읽기 쉬운 코드가 좋은 코드라는 사실을 머리로는 알고 있었다. 하지만 이번 프로젝트에서 적절한 컴포넌트 분리를 통한 관심사 분리, 중복되는 소스코드 방지 등과 관련해 개인적인 학습 및 팀원들과 코드 리뷰를 진행하며 해당 문장의 의미를 조금을 깨달을 수 있었다.
- TanStack Query의 useInfiniteQuery Hook으로 무한스크롤을 구현하거나 option 등을 더 깊이 학습하고 여러 error를 해결하며 TanStack Query 라이브러리를 좀 더 능숙하게 다룰 수 있게 되었다.
- 처음 해보는 작업들이 많아 두려움이 있었지만 이전보다 조금 더 성장하고 싶어 도전을 했고 미숙하지만 작업들을 완료함으로써 많은 것을 배울 수 있었다.(초기세팅, 배포, CI/CD 구축, 소셜 로그인, 공통 컴포넌트 구현, useInfiniteQuery Hook 학습 및 적용)
- 협업 시 원활한 커뮤니케이션을 통해 내가 스프린트 속도를 내야할 때와 혹은 다른 팀원을 도와주거나 도움을 받아야 할 상황을 인지 할 수 있었다. 이를 통해 협업 시 커뮤니케이션이 중요한다는 사실을 다시 한번 느낄 수 있었다.
각자가 맡은 기능을 스프린트 기간내에 구현해주셨던 FE 팀원 분들, 새로운 API 요청 및 수정 작업 요청 시 친절하게 응답해주셨던 BE 팀원 분들, 예쁜 디자인과 활발한 커뮤니케이션을 통해 UI 보완 작업에 도움을 주셨던 디자이너 분 모두 감사드립니다! 다른 팀원들을 통해 많이 배웠고 개발을 혼자하는 것이 아니라 팀원들과 함께 차곡차곡 쌓아나가는 과정이라는 것을 팀원 분들을 통해 알 수 있었던 귀한 시간이었다!