[정원사 프로젝트] 4. 프론트엔드 개발하기

정원사 프로젝트 회고, 프론트 엔드 개발하기

Posted by yoogomja on June 21, 2020

프로젝트 회고 글타래

1. 기획하기

화면 기획전에 필요한 페이지들을 정리해봤었다. 이 작업은 처음에 어느정도 완성을 해두었고, 부가 메뉴등에 필요한 화면과 기능들도 어느정도 미리 준비를 해두었었기 때문에 페이지 구성 자체가 변경되는 일은 많지 않을 것이라 생각했다. 처음에 준비한 페이지 목록은 다음과 같았다.

  1. 대시 보드
  2. 사용자 목록 + 사용자 상세 화면
  3. 사용자 등록
  4. 프로젝트 관리

다만, 첫 기획 당시에는, 글에도 적어놨지만, 사용자 정보가 등록 및 크롤링에만 사용될 줄 알았지 로그인을 거치게 될지는 생각하지 못했었다. 페이지 목록에서 알 수 있을지 모르겠는데, 사용자 등록페이지는 github 계정을 누구든지 입력할 수 있게 해두었었다. 그래서 본인 계정이 아니더라도 등록시킬 수 있고, 본인 계정이 아니더라도 삭제 될 수 있도록 기획했었다. 처음에는 어짜피 내부적으로 사용할 것이고, 외부에서 사용할 일이 없다고 생각했기 때문이었다. 이 기획은 나중에 프론트엔드를 전부 갈아엎게 만드는 사태를 초래하게된다..

어찌되었든, 모든 과정을 내가 진행해야 하는 이런 작은 프로젝트를 수행할 때 특히 오래 걸리는 구간들이있다. 첫번째는 첫 글에서 언급한 기획부분이고 둘째는 그 연장선인 프론트엔드 화면 기획 및 디자인이다. 레이아웃을 결정하는데에는 항상 오랜 시간이 걸리고 그 레이아웃에 맞는 디자인을 결정하는 일은 정말 더 오래걸리는 것 같다.

적당한 레이아웃을 찾기 위해서 참고할만 레이아웃 형태들을 웹 UI/UX 유튜브 들이나 핀터레스트에서 시간을 많이 보냈다. 그렇게 찾아본다고 뚜렷한 답이 나오는 것은 아니라서 항상 진행하면서 정말 많은 수정을 거치게된다. 특히 디자인은 정말 기본이 부족하다보니 할때마다 손이 저주스러울때가 있다.

이번엔 평소 다른 홈페이지와 다르게 통계가 많이 노출되는 홈페이지이다보니 기존에 다른 대시보드 디자인들을 참고하게 되었는데, 무슨 이유에서인지는 모르겠지만 좌측 사이드에 Nav바를 위치시키는 레이아웃 형태가 많이 눈에 띄었다. 자주본게 그런 형태다보니 나도 그런 형태를 쫓아가기로했다. 다만, 모바일에서도 사이드 바 형태로 누기에는 화면 너비를 너무 많이 차지했기 떄문에, 모바일에서는 top에 Navbar가 위치시키는 형태로 변경했었다.

이렇다보니 생각보다 모바일, PC 양쪽의 레이아웃을 신경쓰는데 시간이 꽤 많이 들었었다. 처음에 PC만 염두하고 작업했을 때에는 Adobe XD로 디자인을 개략적으로 잡고 그걸 따라서 작업하게 되었는데, 모바일도 지원하는 반응형으로 제작하기로 기획을 변경한 뒤로는 손에 좀 익지 않아서인지 참고만하고 나머지는 직접 눈으로 봐가면서 작업했던 기억이있다. 정말 주먹구구식 기획이라고 할 수 있는 부분이라, 다음에는 좀 더 서류화해서 나중에도 계속 참고할 수 있게 남겨두는게 좋지 않겠나 하는 생각을 했다.

2. 리액트로 시작하기

2.1. 상세 기술 정하기

리액트로 홈페이지를 한두번 만들어본적은 있지만 공부 이외에 바닥부터 직접 만드는 것은 이번에 처음 진행하게 되었다. 그래서 개발 서버가 어떻게 동작하는지, 배포는 어떻게 작동하는지 같은 디테일한 부분부터 많은 부분을 놓치고 있었기 때문에 첫 2일 정도는 공부가 필요했다. 특히 동아리 동생의 권유로 사용했던 reduxreact-thunk가 핵심이었는데, 그 당시에는 저 둘을 왜 사용하는지 조차 잘 몰랐기 때문에 시간이 좀 필요했다.

두 가지 모두 다행히 꽤 좋은 예제가 있었기 때문에, 참고하면서 꽤 빨리 공부하고 바로 적용할 수 있었다. 항상 이런 자료를 볼때마다 얼굴도 모르는 velopert님께 무한 감사를 드리고 있다. 버전업되면서 몇가지 수정사항이 있어서 변경한 것 말고는 큰 문제는 없었다고 생각한다.

이런 공부와 사전조사를 거치고 이번 프로젝트에서 react사용의 목표는 다음과 같았다.

  1. redux 사용해보기
  2. react-redux 사용해보기
  3. 프로젝트를 typescript로 구성하기

위에 공부할때에는 언급되지 않았지만, typescript를 사용하기도 이번에 큰 목표였다. 한번도 사용해보지 않아서 많은 공부가 필요했지만, 여타 다른 언어처럼 함수의 파라미터까지 체크하는 부분과 미리 객체의 내용을 선언해두는 interface같은 부분이 꽤 도움될 것이라고 생각해서 도전해보게 되었다.

이런 부분은 후에, 특히, 서버와 통신했을 때 더 드러났는데, 서버에서 반환하는 데이터 형태를 클라이언트에 선언해둔 덕에 데이터를 가져오는데 굉장히 수월했다. 이전에 프론트엔드 작업 당시에는 정말 귀찮았던 부분이기 때문에, 이런 이점을 만났을 때 어려워도 typescript를 쓰기 정말 잘했다는 생각을 했다.

2.2. 개발 순서 & 프로젝트 구조 정하기

선택하는데 큰 고민을 거치지는 않았지만 react 개발에 경험이 많은 것은 아니었기 때문에 개발 순서와 프로젝트 구조를 구성하는데 꽤 어려움을 겪었다. 둘 다 어떤 정답이 있는 것이 아닌탓도 꽤 있었던듯 하다. 우선 개발 환경을 구성하기 위해 API 서버 측에 proxy설정을 미리 해두었었고, API 서버를 실행하면 자동으로 react의 개발 서버 쪽으로 포워딩하도록 해두었었다. 그 후 내가 예상한 개발 순서는 다음과 같았다.

  1. 폴더 구조 잡기
  2. react-router설정
  3. 공통 API 요청부 개발
  4. 공통 API 요청부의 일부를 reduxreact-thunk로 모듈화
  5. 공통 UI 개발
  6. 화면 마다 3~5의 과정 반복

폴더 구조를 잡는 일은 가장 급선무였다. 이 폴더 구조는 reduxreact-thunk를 공부했던 자료에서 참고해 만들게 됐다. 그래서 많은 창작이 들어가지는 않았다. 그 후에는 react-router로 주소를 어느정도 디자인 해둔 다음, navbar같은 공통 UI를 시작으로 기획한 페이지를 하나씩 개발해 나가기로 했다. 화면의 개발 순서는 다음과 같았다.

  1. 공통 UI
  2. 프로젝트 관리 : 프로젝트 추가, 삭제
  3. 사용자 등록
  4. 사용자 목록 + 사용자 상세 화면
  5. 대시보드

위와 같은 순서로 개발할 요량이었다. 이것도 나름의 이유가 있었는데, 백엔드 개발 후 예상되는 작업 시나리오가 다음과 같았기 때문이다.

  1. 하나의 프로젝트가 등록됨
  2. 사용자의 이름을 등록하고 사용자 정보만 크롤링
  3. 해당 프로젝트에 사용자를 추가
  4. 해당 프로젝트에 등록된 사용자들에 한해 이벤트를 크롤링
  5. 분석 후 대시보드에 출력할 통계 정보 작성

이런 흐름으로 개략적인 서비스가 운영될 예정이었기 때문에 서비스의 순서를 따라서 개발 순서를 정했던 것이었다. 백엔드의 작동순서대로 개발했던터라 이후 개발 순서에 대해서는 큰 문제없이 진행되었었다. 폴더 구조도 많이 복잡하지는 않았다.

1
2
3
4
5
6
7
8
-- src
    ㄴ api          : API 통신 부 
    ㄴ components   : 반복 사용되는 UI 요소들 
    ㄴ lib          : 반복 사용되는 기능 및 함수들 
    ㄴ modules      : redux / react-thunk 가 합쳐진 코드 묶음
    ㄴ scss         : 공통 스타일 태그들
    ㄴ views        : 화면 tsx들 
    App.tsx

api폴더와 modulesreact-thunk공부시에 참고한 자료에서 가져왔고, 나머지는 사용하기 편하다고 생각한 구조로 설정했던 기억이난다. 개발을 마친 지금 생각해봐도 사용에 큰 어려움은 없었고 생각보다 구분도 확실했기때문에 나중에 코드를 되돌아봐도 코드를 복기하는데 어려움은 없었다. 많이들 사용하는 구조는 어떤지 궁금할따름

3. 본격적인 개발

3.1. 라우팅 하기 : react-router

react-router는 자료가 많이 올라와있는 편이라 도입하는데 큰 어려움은 없었다. hooks도 지원해주고 있었기 때문에 코드로 직접 페이지를 이동하는 일도 어렵지 않았다. 사용하면서 어려웠던 점은 내 오히려 레이아웃 때문에 생겼었다. 사용자 목록 + 사용자 상세 정보 페이지였는데, 좀 특이한 레이아웃이 있기 때문이었다. 해당 페이지의 요구사항은 다음과 같았다.

  • 1:3비율로 스플릿된 화면의 1부분은 유저의 목록을 표기
  • 3부분은 사용자의 상세 화면이 출력
  • 이때, /users라는 주소로 접근했을때에는 사용자 목록과 사용자를 선택해달라는 안내 페이지 노출
  • /users/YOOGOMJA와 같은 주소로 접근했을때에는 사용자의 목록과 상세 목록을 같이 출력
  • 만약 주소에서 넘겨받은 사용자의 이름이 존재하지 않는다면, /users/404-not-found페이지로 이동할 것
  • 모바일에서는 사용자 목록이 출력되지 않을 것

이런 요구 사항이 있었는데, (내가 기획했지만) 무려 모바일에서는 아예 출력하지 않아야하는 조건이있었다. 그냥 css로 숨기는 방법도 있었지만, 그럴경우 쓸데없는 서버 요청을 한번 수행하기 때문에 보이지 않게 하는 정도로는 부족했다. 그래서 모바일과 pc를 구분짓는 패키지를 찾아봤고 해당 문제부터 해결해두었었다. 그 뒤에는 저 레이아웃을 처리하는 일이 꽤 어려웠기 때문에 골머리 썩혔던 기억이 난다. SwitchRoute를 적당히 섞어서 해결했지만, 약간 공부가 필요했던 부분이었다. [해결 과정]

3.2. 데이터 다루기 : redux & react-thunk 도입

redux의 필요성을 깨닫는데에는 오래 걸리지 않았다. 리액트를 처음 배우자마자 angular와 다른 구조탓에 컴포넌트들간 데이터 전달이 굉장히 까다롭다는 것을 알고있었기 때문이다. 다만 사용법은 꽤 어려웠기 때문에 학습이 꽤 오래걸렸다. 참고한 자료를 기반으로 데이터 통신에 관여되는 부분들을 모듈안에 작성해두고 데이터가 필요할 때 원하는 thunk를 실행하면 useSelector함수로 해당 데이터를 불러와 사용하는 방식으로 진행되었다. 거의 대부분의 API 통신 내용들은 modules폴더안에 만들어두었었다.

다만, 하나의 API를 추가할 때마다 굉장히 많은 과정이 필요했다. 상태별로 action에 필요한 문자열을 등록하고, typesafe-actions로 비동기 액션을 만든후 thunk를 만들어주고, 해당 모듈의 type에 객체를 등록해주어야 하며, 최종적으로 reducer를 작성해야했다. 일일히 그 작업을 수작업으로 하다보니 하나의 API가 생길 때마다 꽤 많은 시간이 소요되었다.

물론 공부했던 자료에는 몇가지 부분을 일일히 하지않아도 되도록 작성해둔 코드를 제공하고있었지만, 그렇게하면 일부 경우에 자유도가 떨어지게 된다고 판단하여 해당 부분은 빼고 진행했었다.

가장 어렵고 시간이 오래걸리는 부분이었기에, 공부하다보면 끝이 없을 것이라 생각해 우선 모르는 건 모르는 대로 두고 진행해보자는 생각으로 그대로 작업을 진행했다. 다시 되돌아봐도 이 단계에서 시간을 오래 끌었으면 아마 유야무야되지 않았을까 싶다. 다행히 이 작업이 오류는 없었기 때문에, 이후 개발에 속도가 붙었었다.

나중에 깨달았던 점은 모든 데이터 통신을 reduxreact-thunk로 묶어둘 필요는 없다는 점이었다. 자주 사용되는 항목들만 해두면 되는 것이었는데, 처음 공부하다보니 모든 통신에 대해 모두 redux안에 넣어버려 엄청 비효율적인 코드를 쓰게 되었다. 다음엔 필요한 항목들만 작성하는게 좋겠다는 생각을 했다.

3.3. 실제 화면 구성하기

첫 순서로 개발할 것은 공통 UI였기 때문에 데이터 통신을 다룰 필요는 없었다. 공통 UI를 개발하면서 필요했던 것은 HTML구조와 클래스 이름의 룰을 정하는 것 정도였다. 처음 글에 언급했던 몇가지 이유때문에 scss를 쓰게 되었는데, 여기서는 클래스 명을 비교적 보기 좋게 작성해두는게 나중에 다시 보기에도 좋을 것이라 판단했기 때문이다.

그 이후에는 레이아웃대로 화면을 구성하는 과정이 정말 어려웠는데, flexbox를 사용하는게 서툴렀기 때문에 시간을 정말 많이 투자했다. 특히 개발하면서 막혀서 가장 오래 지체된 부분이 이 부분이었다. flex-grow , flex-shrink, flex-basis등이 주요 키워드였고, 해당 속성들을 제법 다루게 된 이후로는 큰 문제는 없었다.

scss를 사용할때에는 변수 기능과 mixin기능을 자주 사용했는데, @media 태그를 작성해야할 때 매우 요긴 하게 작성했다. 그리고 자주 사용되는 색이나 특성들도 미리 분류 해두었었기 때문에 개발속도를 올리는데 굉장히 도움되었었다.

이 후에는 개발하며 input, button같은 자주 반복되는 항목들은 components폴더에 별도로 분류해가면서 작업을 진행했다. 이때 데이터 통신은 미리 준비해뒀던 thunkreact-redux함수인 useSelector를 이용해 데이터를 요청 / 가져오기 하는 방식으로 진행되었다.

이 때 나는 페이지가 몇개의 컴포넌트로 나눠질지 예상하지 않고 최대한 데이터의 단위를 조각조각 내두었기 떄문에, 한 페이지를 로드할때 요청을 3~4개씩 보내는 일도 다반사였다. 지금도 요청이 잦은 것은 좋은 일인지 잘 판단이 서지 않아서 이후에 변경해야할지 조금 고민 중이다.

4. 정리하며

프론트엔드 개발은 항상 더 욕심내게 만드는 매력이 있다. 기술이 자주 바뀌고 새로운 기술이 자주 나오다 보니 약간 오기가 생기게 하는 면이있다고 생각한다. 이번에도 redux, react-thunk 정도만 생각했지만, 정말 의외의 부분(flex 같은..)에서 문제가 생기곤 했기 때문에 아직도 멀었다는 생각을 많이했다. 그래서 1차 완성을하고 꼭 기회가 되면 리팩토링을 하면 좋겠다는 생각을 했었는데 .. 그 시일이 빨리 다가올지는 생각하지 못했다.

주로 사용한 패키지들

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
 "dependencies": {
    "@types/axios": "^0.14.0",                  // 비동기의 타입스크립트 패키지
    "@types/react-datepicker": "^2.11.0",       // 날짜 선택 UI의 타입스크립트 패키지
    "axios": "^0.19.2",                         // 비동기 통신에 사용
    "highcharts": "^8.0.4",                     // 차트를 구성하는데 사용
    "highcharts-react-official": "^3.0.0",      // 차트를 구성하는데 사용
    "language-colors": "^1.181.0",              // github 저장소에서 갖고있는 언어 사용률 표기를 위해 언어별 색을 가져옴
    "moment": "^2.24.0",                        // 날짜 객체를 다루기 위해 사용
    "node-sass": "^4.13.1",                     // react에서 scss를 사용하기 위해 사용
    "nuka-carousel": "^4.7.0",                  // carousel 형태의 UI 구현을 위해 사용
    "react-datepicker": "^2.15.0",              // 날짜 선택 UI 구현을 위해 사용
    "react-device-detect": "^1.12.1",           // 기기의 형태를 가져오기 위해 사용
    "react-icons": "^3.9.0",                    // 필요한 아이콘들을 불러와 사용하기 위해 사용
    "react-redux": "^7.2.0",                    // redux
    "react-router": "^5.1.2",                   // routing을 위해 사용
    "react-router-dom": "^5.1.2",               // routing을 위해 사용 2 
    "redux": "^4.0.5",                          // redux
    "redux-thunk": "^2.3.0",                    // thunk
    "typesafe-actions": "^5.1.0",               // 비동기 액션
    }
}