[TIFY 개발일지 #1] 타당한 근거로 프로젝트를 세팅하자 (with React, Vite, TS)

김유진·2023년 6월 29일
5

React

목록 보기
63/64

6월 말부터 8월 말까지 작은 웹앱 사이드프로젝트를 진행하게 되었다. 이번에 프론트엔드 리드를 맡게 되어서 프로젝트 세팅부터 프론트엔드 전반적인 관리는 내가 맡게 되었다. 당연히 리더로써..컨벤션을 정하고 어떤 것으로 개발을 진행할 것인지 정하는 것이 중요하다. 하고 싶은 대로 하면 안되고, 협업이기 때문에 모든 상황을 고려해서 프로젝트를 세팅하는 것이 매우 중요하다고 할 수 있다.

1. 라이브러리 선택

React를 선택한 이유

이번에 개발은 React 를 주요 라이브러리로 삼고 개발을 진행하게 되었다. 같이 개발을 진행하는 프론트엔드 팀원들이 Next.js를 공부해 본 적이 없기 때문에 프로젝트를 진행하면서 동시에 Next.js를 배우는 데에는 큰 부담감이 존재할 것 같아서 선택하게 되었던 것 같다. 또한, 이번에 만들게 되는 프로젝트의 최종 배포는 웹 앱으로 애플 스토어구글 스토어 에 업로드할 계획까지 있기 때문에 클라이언트 단에서 화려한 애니메이션과 터치모션을 구현해야 하기 때문에 서버사이드 랜더링보다는 클라이언트에서 랜더링을 처리하고 DOM을 조작하는 것이 UX 향상 면에서는 가장 좋을 것이라고 생각하여 React로 개발하는 것이 좋을 것이라고 생각하였다.

Vite를 선택한 이유

Vite는 현재 빠른 속도의 번들링 툴로 주목받고 있는 번들링 도구이다. 보통 React를 이용하여 서비스를 만든다고 생각하면 CRA 명령어를 우다다 쳐서 만들 수 있겠지만, 그렇게 된다면 패키지 관리가 복잡하고, 번들링 속도가 너무 느리기 때문에 (심지어 개발환경 띄우는 것도 느림) Vite를 선택하게 되었다.

yarn berry 도입하기

요즘 습관처럼 대입하고 있는 yarn berry 이다. zero-install로 패키지를 따로 다운받는

yarn

이라는 명령어를 입력하지 않아도 되고, git에서도 편리하게 패키지를 관리할 수 있기 때문에 최근 적극적으로 사용하게 되었다.
가장 좋았던 점 중에 하나는, node_modules 로부터의 해방이다.

node_modules 의 고통

프론트엔드 개발자라면 node_modules를 지웠다 깔았다 하는 경험이 있었을 것이며, 이 무거운 node_modules 를 삭제하는 것만으로도 (까는 것만으로도) 굉장히 오랜 시간이 걸리기 때문에 컴퓨터 앞에서 멍 때린 경험이 있을 것이다. 필자는 과거 굉장히 저스펙의 노트북 하나로 프로젝트를 하느라 node_modules 를 까는데 15분까지 걸려본 적 이 있다. 하지만 yarn berry를 사용하면서 PnP를 도입하게 되었고, 의존성 구조를 zip코드로 관리할 수 있게 되어 의존성 설치와 관리가 매우 편리해지게 되었다.
이에 관련된 글은 이전에 작성한 적이 있어 이번 글에는 간단하게 작성하고 넘어간다.
이전 글 보기
참고한 글 보기

2. 세팅하면서 마주한 오류들 해결하기

자. 위에 내용은 이전에도 관련된 글을 작성한 적이 있어 매우 간단하게 작성하였는데, 사실 이 글을 작성한 이유는 아래부터 시작이다.

타입스크립트를 인식하지 못하는 개발환경 다운그레이드하기


Vite 최신버전 + React 최신버전 + Typescript를 모두 최신버전으로 사용하다 보니 아직 안정화되지 않은 부분들에 있어서 모듈을 불러오는 데 pnp가 인식하지 못하고 패키지를 찾지 못하는 것 같은 현상이 일어났다. 그렇기 때문에 기존에 사용하던 타입스크립트 5.1.2 버전을 4.9.5 버전까지 낮추어 재설치하였더니 모든 파일 모듈 인식이 문제 없이 잘 돌아가는 것을 확인할 수 있었다. 개인적으로 모든 패키지와 라이브러리들을 최신 버전으로 사용한다면 좋겠지만, 아직 안정화가 서로서로 되어 있지 않은 부분들이 있어서 최대한 호환되는 버전까지 내려서 개발을 진행하고자 한다.

그래도 번들링하는 데 있어 몇몇 오류들이 온전히 해결되지 않은 현상들이 있었는데..그것은 바로 tsconfig 세팅 때문이었다.

"compilerOptions": {
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
      ...

moduleResolution이 처음에는 bundler로 세팅되어 있었다. 기존 프로젝트에서는 계속해서 Node로 세팅되어 있었는데,이게 왜 다르지 ? 하고 Node 로 바꾸어 보니까 정상적으로 실행되는 것을 알 수 있었다.
사실, moduleResolutionbundler 로 설정되어 있는 것은 처음 보아서, 이 부분이 신기하여 조금 찾아보았다.

그 결과, 타입스크립트 5.0 이상부터는 moduleResolution: bundler을 지원해준다. 그래서 최신 버전의 Vite에서 자동으로 최신 버전의 타입스크립트를 사용할 줄 알고 미리 설정해 준 것이다. 하지만, 이번 프로젝트는 4.9.5 버전의 타입스크립트를 쓰기 때문에 아쉽지만 Node 로 바꾸어야 했고, 이를 해결하니 모듈 오류가 발생하지 않는 것을 확인할 수 있었다.

3. 컨벤션 세팅하기

폴더구조

📦 src
┣ 📂 components
┃ ┗ atoms (storybook으로 제작할 자주 사용하게 될 재사용 컴포넌트)
┃ ┗ errors
┃ ┗ layouts
┃ ┗ (기능) //추후 페이지에 따라서 추가될 컴포넌트들을 폴더명으로 생성
┣ 📂 pages
┃ ┗ 📂 Home
┃ ┃ ┗ index.tsx
┃ ┗ 📂 login
┃ ┃ ┗ index.tsx //NextJs같은 page 폴더구조 가지도록 
┣ 📂 utils(인스턴스/공통 함수 작성)
┃ ┗ instance.js
┣ 📂 hooks
┣ 📂 lib
┣ 📂 assets
┣ 📂 styles (global style 저장)

폴더 구조는 위와 같이 설정하였고, 최근 들어 유행(?) 처럼 번지고 있는 page 폴더구조를 간소화하는 방법으로 만들어 보고자 하였다.
큼지막한 페이지들은 대부분 SPA 로 운영되기 때문에 index.ts 로 폴더 단위로 이를 확인할 수 있어 개발하는 입장에서 복잡한 페이지 구조에서 헤매지 않아도 된다. 더불어, 페이지에서는 페이지만 보여주고, 나머지 복잡한 부분은 컴포넌트 단위로 쪼개서 기능별로 구현할 수 있으니 편리하게 기능 위주로 개발을 할 수 있을 것이다.

eslint

eslint 를 설정하지 않고 빌드했다가 낭패를 본 적이 있기 때문에 이번에야말로 rule를 꼼꼼히 정리하잣. 유용하고 필요한 부분만 정리해서 넣는다. UI는 스토리북을 이용하여 css-in-js 로 개발을 진행할 것이기 때문에 이에 관련된 eslint 설정도 추가로 넣어준다.

 plugins: ['react-refresh', 'react', 'react-hooks', '@typescript-eslint', 'prettier'],
  rules: {
    'react-refresh/only-export-components': 'warn',
    'react/react-in-jsx-scope': "off",
    '@typescript-eslint/no-var-requires': 'off',
    '@typescript-eslint/no-empty-function': 'off',
    'react/no-unknown-property':['error', {'ignore':['css']}],
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': [
      'warn',
      { 'ignoreRestSiblings' : true}
    ]
  },

prettier

{
    "singleQuote": true,
    "semi": true,
    "useTabs": false,
    "tabWidth": 2,
    "trailingComma": "all",
    "printWidth": 80,
    "bracketSpacing": true,
    "bracketSameLine": false
  }
  

협업을 하기 때문에 프리티어를 설정하지 않으면 코드가 뒤죽박죽 섞이게 되어 버린다. 컨벤션을 협의하여 정하고 가장 보편적으로 쓰이는 것으로 설정하자. 협업할때 프리티어 설정은 정말 필수라고 할 수 있다. 일관성을 유지해야 읽기 좋은 코드가 되기 때문이다.

절대경로 설정

Vite는 절대경로 설정하기 위해서는 tsconfig 가 아니라, vite.config 파일에서 해 주어야 한다.

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  base:'./',
  plugins: [react()],
  assetsInclude:['**/*.jpg'],
  resolve: {
    alias: [
      { find: '@pages', replacement: '/src/pages' },
      { find: '@components', replacement: '/src/components' },
      { find: '@lib', replacement: '/src/lib' },
      { find: '@assets', replacement: '/src/assets' },
    ],
  },
})

이렇게 자주 쓰는 경로들은 절대경로로 관리할 수 있도록 한다. 같은 폴더에 있는 컴포넌트를 불러와도 파일을 깔끔하게 유지할 수 있다는 것이 장점이다.

../../../login/Button

이렇게 만들기보다는

@components/Button

위와 같이 단순화를 할 수 있다. 코드가 매우 간결해져 보기도 편하고, 어떤 파일을 참조한 것인지도 명시적으로 확인할 수 있다.

4. 스토리북 생성하기

이번 프로젝트는 디자이너와의 소통이 매우 핵심적이다.
인터렉티브한 효과들이 앱에 많이 들어가게 되고 매끄러운 UX를 위해 컴포넌트를 개발해야 하기 때문이다.
그래서 framer-motion 을 자유롭게 사용할 수 있고, 배포한 것과 별반 차이가 나지 않는 것 같은 프레이머를 이용하여 디자이너와 프로토타이핑을 소통하려 하였으나, 디자이너 분들이 프레이머를 배울 시간이 부족한 점,또한 이번에 피그마 대규모 업데이트를 통하여 프로토타입 기능이 대폭 강화되었을 뿐만 아니라 dev Mode 까지 생겨 개발자와 디자이너의 협업을 더욱 매끄럽게 할 수 있다는 것 또한 인상깊었다.
그렇기 때문에 새롭게 업데이트 된 피그마로 프로토타이핑 + 디자인을 진행하기로 하였고, 피그마로 만들어진 컴포넌트들을 소통하기 위하여 스토리북으로 원자 단위로 나눌 수 있는 기본적인 컴포넌트들을 만들고 이를 배포하여 함께 관리하기로 했다.
위에서 언급했듯이 스토리북은 컴포넌트 폴더 - 아톰 폴더에서 관리를 할 예정이다. 그렇기 때문에 스토리북을 어디서 인식할 수 있는지 main.ts 가 알아들을 수 있도록 해주어야 한다.

const config: StorybookConfig = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    path.dirname(
      require.resolve(path.join("@storybook/addon-links", "package.json"))
    ),
    path.dirname(
      require.resolve(path.join("@storybook/addon-essentials", "package.json"))
    ),
    path.dirname(
      require.resolve(
        path.join("@storybook/addon-interactions", "package.json")
      )
    ),
  ],

빠밤. 스토리북 납시오. 가장 중요한 부분은 스토리의 경로를 바꾼 부분이라고 확인할 수 있다.
스토리북 빌드하려고 자꾸 에러가 났던 부분인데, 마지막 빌드하기 전에 @storybook/addon-links 패키지 잘 깔려 있는지 확인하고 빌드하길 바란다!
이렇게 해서 기본적으로 보일러플레이트 코드를 작성하고, 개발할 수 있는 환경을 만들어 놨다.

이렇게 내가 리드로 진행하게 된 프로젝트라 그런지(?) 조금 더 소중히...ㅎㅎㅎ 근거를 가지고 프로젝트를 세팅하게 되었던 것 같다. 이번에 프로젝트를 세팅하였던 모든 과정들을 훑어온 것 같아서 글을 작성하면서도 프로젝트를 어떻게 설계해 나갈 것인지에 대해서도 근거를 가지게 될 수 있는 것 같았다. 다음 글에서는 배포에 관련된 글을 작성해보고자 한다. (도커와 github action을 이요한 CI구축) 파이팅!

1개의 댓글

comment-user-thumbnail
2023년 7월 14일

짱이다

답글 달기