본문 바로가기

엘리스 sw 엔지니어 트랙 2기

엘리스 1차 프로젝트 회고

반응형

미루고 미뤘던 1차 프로젝트 회고 글을 이제서야 쓴다.

 

내가 이 글을 쓰는 이유는 내가 했던 것들을 기록하기 위함이기도 하지만, 엘리스 sw 엔지니어 트랙을 고민하는 사람들에게 정보를 주기 위함이기도 하다. 또한 미래의 엘리스 레이서분들이 프로젝트를 진행하면서 혹시나 이 글을 보게 된다면 참고해도 좋을 것 같다. 느낀점 위주로 적을거라 생각보다 참고할게 없을 수도 있다...ㅎㅎ

 

Vivid Clothes

https://github.com/dsyhwk1016/VividClothes

 

GitHub - dsyhwk1016/VividClothes: shopping mall project with vanilla javascript

shopping mall project with vanilla javascript. Contribute to dsyhwk1016/VividClothes development by creating an account on GitHub.

github.com

먼저 1차 프로젝트 결과물이다. 놀러오세용. 참고로 이는 2주 동안의 결과물은 아니고 '2주 + 업그레이드 스터디' 결과물이다. 나는 사용자 파트를 담당했고, 아래의 페이지들을 직접 구현했다.

장바구니, 홈, 주문, 제품상세, 주문상세, 리뷰, 주문내역 페이지

 

프로젝트 진행 방식

기간:  2주
주제:  쇼핑몰 (공통 주제)
사용 언어:  Vanilla Javascript (React, Vue 사용 금지)
팀당 인원:  4명(Front 2 + Back 2) or 5명(Front 3 + Back 2) 

 

기본적인 정보는 이정도라고 할 수 있겠다. 추가로 팀마다 포지션별로 코치님이 한 명씩 붙는데, 격일로 1시간씩 오피스아워 시간이 있기 때문에 개발 중에 질문 사항이 있으면 얼마든지 질문할 수 있다.

 

스켈레톤 코드는 주어진다. 기본적인 폴더 구조와 로그인, 회원가입 페이지 정도는 이미 구현된 상태로 시작한다. 그런데 말그대로 스켈레톤 코드라 디자인이 별로기 때문에 폴더 구조만 그대로 놔두고 다 갈아엎어야 할 것이다. 

 

주제는 쇼핑몰로 공통주제지만 바꿔도 상관 없다. 그런데 2주라는 시간이 많이 촉박하기 때문에 주제는 바꾸지 않는 것을 추천한다. 쇼핑몰도 종류가 굉장히 많기 때문에 어떤 컨셉으로 갈지 결정하는 것도 쉽지 않다. 우리팀 같은 경우 컨셉을 '편집샵'으로 정했다. 

 

팀당 인원은 어떤 기준으로 정해지는지 모르겠다. 우리 팀은 4명이었다. 나는 개인적으로 5명은 많다고 생각해서 오히려 좋았다. 

 

매주 토요일마다 코치님들이 코드 리뷰를 해주신다. 프로젝트 기간이 2주이기 때문에 두 번의 코드 리뷰를 받을 수 있다.

 

 

협업 경험이 없어도 너무 걱정하지 않아도 된다. 엘리스에서 메뉴얼을 다 작성해주기 때문에 그대로 따라가기만 하면 된다. 나 또한 협업이 처음이었어서 걱정이 많이 됐었지만, 결론적으로 따라가는데 크게 문제 없었다. 다만 처음 이틀 정도는 애먹을 수 있다. 특히 git 이 은근 시간 많이 잡아먹는다. 그런데 보통 팀원중 최소 한명은 협업 경험이 있는 사람이기 때문에 모르는건 물어보면 된다. 물어보는 것을 절대 부끄러워 하지 말자. 

 

느낀점 및 고민들

1. 기획의 중요성

나는 이 프로젝트가 첫 협업 프로젝트였기 때문에 첫날에 뭘 해야할지 몰랐다. 정확하게는 어디서부터 시작을 해야 할지 몰랐다. 무작정 코딩을 하기는 했는데(뭘 했는지도 기억 안남) 결과적으로 아무 쓸모 없었다. 그렇게 이틀 정도 스켈레톤 코드를 구경하면서 아무것도 못했다. 이런식으로 가다가는 진짜 망할 것 같은 느낌이 들어서 3일차에 긴급 소집을 했다.

 

그렇게 3일차에 다른 프런트 분과 카페에 앉아서 거의 8시간 동안 회의를 진행했다. 팀원분과 나는 8시간동안 페이지 구성 및 기능을 확립하고 문서화했다. 아래는 첫날 회의의 결과물이다. 마음 같아서는 figma로 페이지 하나하나를 직접 디자인하고 싶었는데 그러면 2주만에 프로젝트를 끝낼 자신이 없었다. 만약에 첫날부터 진작에 만나서 진행했더라면... 가능하지 않았을까 하는 생각이 든다.

 

 

전체적인 구조가 잡히고 나니 분업이 가능해졌다. 나는 사용자 파트를 담당하기로 했고, 다른 팀원분은 관리자 파트를 담당하기로 했다. 이렇게 4일차가 되어서야 비로소 생산성 있는 코딩을 할 수 있었다. 

 

 

기획이 확실하지 않으면 일이 진행될 수 없다. 설사 일이 진행된다 하더라도 다시 원점으로 돌아갈 것이다. 프로젝트를 고속도로에 비유한다면 기획은 이정표에 대응된고 생각한다. 기획 없는 프로젝트는 이정표 없는 고속도로와 똑같다. 기획이 튼튼할수록 프로젝트의 방향성이 확실해지기 때문에 일의 진행 속도도 빨라진다. 따라서 프로젝트는 무조건 기획부터 시작하자! 그리고 기획만큼은 꼭~~ 만나서 하자. 

 

주의할 것은 기획을 애매하게 하고 시작하면 다시 원점으로 돌아가기 때문에 꼭꼭 확실하게 하고 넘어가야 한다. 경험상 페이지 구조와 기능만 확실하게 잡아도 일을 진행하는 데에 크게 무리는 없다. 그리고 개발을 진행하다보면 반드시 바뀌는 부분이 생기는데 변경된 부분은 반드시 모든 팀원이 알고 있어야 한다. 당연해 보이지만 생각보다 쉽지 않다. 

2. 장바구니를 어떻게 구현할 것인가

프로젝트 요구사항 중에 장바구니를 로컬에 저장해야 한다는 조건이 있었다. 내가 생각한 방법은 LocalStorage를 사용하는 방법과 indexedDB를 사용하는 방법, 이렇게 두 가지였다. 어떤 것을 사용할지 고민하다가 용량이 훨씬 큰 indexedDB를 선택했다.

 

LocalStorage는 용량 제한이 5MB 정도에 불과하지만, indexedDB는 HDD 용량의 50% 정도라고 한다. 이는 대략적인 수치로, 실질적으로는 브라우저마다 편차가 있다. 사실 장바구니 데이터를 저장하는데 indexedDB를 사용하는것은 과할 수 있지만 그래도 부족한 것보다는 넘치는게 낫다고 생각한다. 그리고 이참에 indexedDB를 배워보고 싶었다. 

 

indexedDB 사용법만 익히면 장바구니 구현은 크게 어렵지 않다. 사용자 ID를 localStorage에 저장해놓기 때문에, ID별로 새로운 DB를 생성하고, 로그인시 ID를 식별자로 사용해 DB에 연결하면 된다. 여기에 cart라는 스토어를 생성해서 사용자가 제품을 장바구니에 넣으면 제품명, 사이즈, 가격, 수량 등을 저장하면 된다. 

 

나는 indexedDB를 좀 더 활용해서 일반 주문 데이터도 따로 저장했다. 일반 주문 데이터란 사용자가 제품 페이지에서 바로 '주문하기' 버튼을 눌렀을 때의 데이터를 말한다. 

 

사용자가 주문 페이지로 이동하는 루트는 크게 두 가지다. 첫번째 경우는 장바구니에서 주문 버튼을 클릭할 때고, 두번째 경우는 제품 상세 페이지에서 다이렉트로 주문 버튼을 클릭할 때다. 나는 이 두 경우를 쿼리스트링으로 구분했다. 장바구니를 통하면 주문 페이지 URL에 '?storeName=cart'를 넣어줬고, 다이렉트로 주문 버튼을 클릭하면 '?storeName=order'를 넣어줬다. indexedDB 스토어도 cart, order로 각각 생성해서 두 경우를 구분해 저장했다.

 

쿼리스트링의 value 값과 indexedDB의 store 이름을 일치시킨 덕분에 주문 페이지에서 쿼리스트링 값으로 어느 store를 연결해야 하는지 쉽게 알 수 있었다. 

3. 반응형(모바일 퍼스트)에 대한 고민

반응형은 프로젝트를 제출하고난 이후에 진행했다. 팀원들과 합의하에 2차 스터디로 '1차 프로젝트 업그레이드' 팀을 만들었고, 3주 동안 틈틈이 진행했다.

 

원래 모바일을 전혀 고려하지 않았기 때문에 모바일 퍼스트로 바꾸기 위해서는 css 코드를 거의다 바꿔야 했다. 반응형을 꼭 적용해보고 싶었기 때문에 코드를 갈어엎는 것에 망설임은 없었다. 지원 기기는 모바일, 태블릿, 데스크탑으로 정했고 분기점은 768px, 1024px로 정했다. 몇픽셀을 분기점으로 삼아야 할지는 너무 다양해서 그냥 가장 보편적인 값으로 정했다. 코드로 보면 아래와 같다. 

 

/* 모바일 */

/* 태블릿 */
@media (min-width: 768px) {}

/* 노트북, 데스크탑 */
@media (min-width: 1024px) {}

 

반응형은 크게 어려운 건 없었다. 다만 시간이 좀 걸릴 뿐이었다. 재사용할 것은 최대한 재사용하면서 스타일링 했다. 아래는 사용자 주문 내역 페이지로, 왼쪽이 데스크탑 버전이고 오른쪽이 모바일 버전이다. 

 

데스크탑 버전(좌), 모바일 버전(우)

4. 이벤트 위임 문제

이벤트 위임을 잘 활용하면 불필요한 이벤트 등록과 코드의 중복을 피할 수 있다. 코딩을 하다보면 이벤트 콜백함수의 로직이 거의 똑같은게 몇몇 존재한다. 나같은 경우 제품 상세 페이지에서 수량 조절 버튼의 로직이 거의 동일했다. '+' 버튼과 '-' 버튼의 차이점이라고는 '수량 += 1', '수량 -= 1' 뿐이었다.

 

수량 조절 버튼

 

이벤트 위임에 대한 개념을 몰랐을 때는 이벤트 핸들러 함수를 따로 빼서 파라미터를 넘기는 식으로 해결했다. 코드로 보면 증가 버튼, 감소 버튼을 각각 upBtn, downBtn이라고 했을 때 아래와 같다.

 

upBtn.addEventListener('click', (e) => handleClickBtn(e, 'up')) 
downBtn.addEventListener('click', (e) => handleClickBtn(e, 'down'))

 

이렇게 하면 handleClickBtn 함수 내부에서 분기처리로 로직을 재활용 할 수 있다. 그러나 뭔가 굉장히 아쉬웠다. '요소를 추가할 때 이벤트가 자동으로 등록되게 하는 방법은 없을까?'를 계속 고민하던 와중에, 이벤트 위임이라는 개념을 알게 되었다. 나는 이벤트 위임을 활용해 상위 요소에만 'click' 이벤트를 걸어주고, 하위 요소들은 이벤트를 받아 쓰는 방식을 적용했다. 예시 코드는 아래와 같다.

 

<div id="container"> 
	<input class="upBtn" type="button"> // 추가된 요소 
</div>

 

이렇게 하면 container 요소에만 'click' 이벤트를 걸어주고, 이벤트 핸들러 함수 내부에서 'e.target.className'으로 하위 요소를 식별할 수 있다. 굳이 '+', '-' 버튼에 또 이벤트를 등록할 필요가 없는 것이다. 이벤트 위임은 매우 유용하니 꼭 적용해보기를 바란다.

5. 이벤트 콜백 함수에 파라미터 전달

이건 그냥 꿀팁이다. 프로젝트를 진행하면서 한번쯤은 이벤트 콜백 함수에 파라미터를 전달하고 싶거나, 이벤트 콜백 함수를 밖으로 빼내고 싶은 일이 생긴다(아님 말고). 방법은 아주 간단한데, 아래와 같이 하면 된다. 아래는 내 코드의 일부분을 가져온 것이다. 

 

upButton.addEventListener('click', (e) => handleUpDownButton(e, result, 'up', setTotalPriceSum));
const handleUpDownButton = (e, result, type, setTotalPriceSum) => {
    // code
}

흥미로웠던 이슈 

마지막 배포 과정에서 발생했던 이슈다. iOS 운영체제 환경에서 접속하면 흰 화면만 보였다...!! 나는 맥이랑 아이폰이 같은 운영체제인줄 알았는데 맥은 macOS이고, 아이폰이나 아이패드는 iOS 운영체제다. macOS에서는 문제 없이 잘 접속되었는데 iOS만 말썽이었다. 노트북에 연결해서 개발자 도구를 들어가보니 아래와 같은 오류 문구가 있었다. 

이게 뭔가 싶어 구글링을 해봤는데, 너무나 황당한 이유였다. 바로 정규표현식의 특정 문법 때문이었다. 원인은 IOS에서 지원하지 않는 lookahead, lookbehind 문법을 사용했던 것!! 이게 뭔지 궁금한 사람은 여기를 참고하면 된다. Can I Use 에서 검색해보니깐 안된다고 나오기는 하더라..

 

 

Safari on iOS를 보면 전부 빨간색임을 확인할 수 있다. 그런데 이상한 점이 한 가지 있었다. 분명 크롬 브라우저는 초록색으로 표시되어 있는데 아이폰 크롬 브라우저로 접속했을때 똑같은 현상이 발생했다. 이것도 새롭게 알게된 사실인데 iOS에서는 크롬도 사파리 렌더링 엔진을 써야한다고 한다. 고약한 애플...

 

아쉬운 점

먼저, div를 남용한게 많이 아쉽다. 코드를 뜯어보면 수많은 div 태그를 볼 수 있을 것이다. 다음에는 꼭 시맨틱 태그를 적용해서 의미 있는 웹페이지를 만들어야겠다. 

 

다음으로, 최적화까지 해보지 않은게 많이 아쉽다. 뒤늦게 lighthouse라는 확장 프로그램을 알게 되어서 적용해봤는데, performance 점수가 무려 58점이었다...😱  가장 큰 원인은 이미지 크기로 예상된다. 아마 이미지 resizing만 거쳐도 성능이 크게 향상될 것으로 생각된다. 최적화는 꼭 해봐야겠다!

 

 

반응형