Week12 - 실전 프로젝트를 진행하며 사용해본 기술들

pds·2023년 2월 5일
0

WIL

목록 보기
11/12
post-thumbnail

드디어 실전 프로젝트를 출시 했다.

사용해본 기술들을 간단하게 정리해보았다.


협업을 위한

Typescript

코드를 작성하는 시점에는 어렵고 귀찮더라도 사전에 타입 미스로 발생하는 에러들을 식별하고

타입을 지정해 컴포넌트 또는 함수를 사용할 때 편리함을 누리고자 타입스크립트를 도입했다.

초반에는 어려움이 있었지만

팀원도 그렇고 코드의 양이 많아지고 어플리케이션이 복잡해질수록

없었으면 정말 힘들었겠다 싶어 도입하길 정말 잘했다는 생각을 했다고 한다.


Eslint, prettier

최소한의 클린코딩과 협업 시 코드 포맷팅 동기화를 위해 사용했다.

prettier의 경우 개인 ide 환경마다 기본값이 다를 수 있기에 프로젝트에 팀의 취향을 반영해 따로 설정해뒀다.

eslint의 경우 기본적으로 활용하되 이전 프로젝트의 경험들에서 하나의 컴포넌트가 많은 것들을 import해서 사용할 때 규칙없이 아무렇게나 꼬여있어 무엇을 활용하고 있는지 식별하기 어려웠던 점을 같이 이야기해보며 조사하여 import order 설정을 했다.

eslint-plugin-import 라는 라이브러리로 조사했을 때 알게되었던 적절한 규칙에 더해 우리의 입맛에 맞게 임포트 순서를 지정했다.

순서

  • 내부모듈(또는 리액트 관련) EX) react, react-router, react-router-dom
  • 외부 라이브러리 모듈
  • 내부 파일 모듈 (type-alias)
  • 내부 컴포넌트 모듈 (type-alias)
  • 내부 타입 모듈 (type-alias)
  • sibiling 등 내부 모듈 (non - type-alias)
"import/order": [
      "error",
      {
        "groups": ["builtin", "external", "internal", "object"],
        "pathGroups": [
          { "pattern": "react", "group": "builtin" },
          { "pattern": "react-dom", "group": "builtin" },
          {
            "pattern": "react-router**",
            "group": "builtin"
          },
          {
            "pattern": "@components/**",
            "group": "internal",
            "position": "before"
          },
          {
            "pattern": "@customTypes/**",
            "group": "internal",
            "position": "after"
          },
          {
            "pattern": "@**/**",
            "group": "external",
            "position": "after"
          }
        ],
        "pathGroupsExcludedImportTypes": ["react", "react-dom", "react-router"],
        "newlines-between": "always",
        "alphabetize": {
          "order": "asc",
          "caseInsensitive": true
        }
      }
    ]

craco

Create-React-App Configuration Override의 약자로 create-react-app 설정에 설정을 오버라이딩 하기 위해 쓴다.

우리 프론트엔드 팀은 실전 프로젝트 시작 전

이전까지의 작은 여러 프로젝트 경험을 거치면서 상대 경로의 불편함에 대해 생각해보았고

조사해보고 별칭을 이용한 절대 경로 사용을 위해 craco를 도입하였다.

      "@components/*": ["./components/*"],
      "@assets/*": ["./assets/*"],
      "@pages/*": ["./pages/*"],
      "@styles/*": ["./styles/*"],
      "@hooks/*": ["./hooks/*"],
      "@redux/*": ["./redux/*"],
      "@utils/*": ["./utils/*"],
      "@apis/*": ["./apis/*"],
      "@constants/*": ["./constants/*"],
      "@customTypes/*": ["./types/*"]

이렇게 주요 디렉터리에 대한 별칭을 tsconfig.paths.json에 명시해주고

craco.config 파일에 매핑해준 뒤 tsconfig에 상속 설정해 오버라이딩 해주면 된다.


storybook

UI적인 컴포넌트 개발의 어려움

컴포넌트 깊숙한 곳에 위치하면서도 상호작용이나 애니메이션 같은 이벤트가 많은 독립적인 컴포넌트일 경우 개발이 어려웠다.

또 개발을 해두었더라도 추가/변경이 필요할 때 독립적으로 잘 추가되거나 변경되었는지 확인도 어려웠다.

어떤 컴포넌트는 게임이 종료되어야 한 번 볼수 있는 것이 있었는데 개발/수정하며 게임을 직접 돌려봐야하는 어려움이 있었다

코드리뷰, 이해의 어려움

스토리북 적용 전 까지 필요하다면 리뷰어의 이해를 돕고자 PR에 움짤을 남기는 식으로 협업했었는데 귀찮은 부분도 있고 움짤이 없는 이벤트는 직접 결국 돌려봐야 하며

움짤이 없다면 코드만 보고 컴포넌트를 이해해야 했다.

그래서 도입

개발하는 개발자가 컴포넌트를 테스트하며 쉽게 개발하게 할 수 있을 뿐 아니라 협업하는 사람도 쉽게 컴포넌트를 확인해보고 이해도를 높일 수 있었다.

스토리가 몇 개 없기도 하고 정말 스토리북의 스ㅌ 정도만 활용해봤다고 생각함에도 정말 편리했다. 진작 도입하고 시작할걸..


배포 자동화도

CI 워크플로우를 작성해 PR시 자동으로 스토리북이 배포될 수 있게 하여 리뷰어가 클릭해서 들어가면 바로 볼 수 있게 해두었다.

혜연님은 분명 로컬에서 브랜치를 해당 PR로 돌려 실행 한 뒤 확인해보지 않으셨을 것이다.

다만 마지막 커밋 헤더에 [skip ci] 를 안 붙이면 스토리북 작성을 안했음에도 배포를 하기 때문에 좀 비효율적인 면이 있다. (CI돌리는 시간도 결국 다 비용일 것이라 생각한다)

다음에 이런식으로 또 사용하게 되면 PR에 특정 라벨을 붙여야 스토리북 CI가 돌아가게끔 설정해두어야 겠다.

스토리북을 사용하니 디자이너님과의 소통에도 도움이 되었다.

유저 피드백을 반영해야 하는데 변경사항이 있을 때마다 디자이너님을 젭에 호출할 수는 없지 않은가

하다보니 프론트 팀원과만 의사결정을 하고 빠른 선조치? 후보고를 하게 되었는데 이런식으로 소통에 활용할 수 있어서 좋은 것 같다.

우선 작업해서 PR올려두고 검사를 받았고 확인하신 후 머지했다


기능을 위한

socket.io-client

서버와 실시간 통신을 위해 소켓을 사용하였다.


webRTC

클라이언트들 간 미디어스트림 교환(캠/마이크 사용)을 위해 사용하였다.

peer connection시 구글 STUN서버와 함께 구축해둔 TURN 서버도 사용하게 설정했다.


redux

비동기 api 데이터 관리할게 많았다면 사실 recoil을 클라이언트 상태관리도구로 사용하고

react query를 도입했겠지만 비동기 api 관리할 게 거의 없기도했고

팀원 모두가 slice로 비슷한 책임끼리 응집화 된 상태 데이터를 지정된 reducer로 갱신하는 방식을 선호하는 점과

한 명은 recoil을 사용해보지 않은 점 등을 고려해 리덕스를 도입했다.


써보니

초기에는 괜찮았는데 예상하지 못한 추가되어야 하는 상태 또는 리듀서가 계속 나와 유지보수가 쉽지 않았다.

추가되어야 하는 상태는 과연 여기 slice에 들어있어도 되나? 라는 응집도에 대한 고민도 있었고

매우 작은 단위의 상태 하나에 대해서만 추가하고 신경쓰고 싶은 상황도 있었고

리듀서를 계속 추가해야 되는 불편함도 있었다.

물론 리코일을 도입했으면 또 아 그냥 리덕스 쓸 걸 했을 것이다.

리코일은 devtool이 없기도 했고 상태를 어떤 동작으로 바꾸는지(뭘 추가하는지 지우는지 수정하는지 등) 명시되어있는 것이 없어 직접 찾아봤어야 할 것 같다.


Styled-components

개별 컴포넌트에 대한 동적 스타일링을 위해 딱히 대안을 고려하지 않고 도입했다.

본인은 항해오기 전 emotion 만 사용해보았었는데 문법이 같겠지만 항해에서는 styled-component만 배웠기 때문에 혹시 몰랐던 점, 우리는 ssr 적용과 관련이 없다는 점을 고려해

더 많이 사용되고 있는 styled-component 를 도입했다.

emotion도 사용법이 비슷하지만 일단 항해에서 배웠으니깐! 팀원도 편할 것이라 생각했다.

styled-component에서 제공하는 global style로 앱 전역에 스타일링을 적용했고

theme와 타입스크립트 설정도 적용하여 일부 변경 가능성이 있고 자주쓰이는 속성들은 전역적으로 다른 컴포넌트에서 편하게 사용할 수 있게 설정해두었다.


json-server

원래 초기에 도입을 아예 고려하지 않았었다.

하지만 아쉽게도 몇 개 있지도 않은 백엔드 rest api쪽 개발 속도가 너무 안나와

프론트 팀 회의 후 프론트에서 당장 할 일 공백이 있는 상황이 생길 것을 고려해 도입했다.

안그래도 할게 많았는데 당장 할 수 있는게 없는 상황이 되면 곤란했다.

명세에 맞춰 가짜 express 서버를 구성해 최소한의 응답과 에러 상황만 추가해 리액트에서 사용해보며 개발할 수 있게 구성했다.


profile
강해지고 싶은 주니어 프론트엔드 개발자

0개의 댓글