ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 생산성 향상을 위한 모노레포 도입기
    R-WMS 2022. 8. 7. 21:25

     

    모노레포의 도입 이유

    먼저 모노레포란 두 개 이상의 프로젝트에 동일한 코드가 적용될 때 효율적인 프로젝트 구성을 위해 개발된 전략이다.

    내가 개발하고있는 R-WMS 프로젝트는 다음과 같은 구조로 버전관리를 하고 있다.

     

     


     

    나의 개발상황

     

     

     

     

    자사 어드민(R-WMS ADMIN) 도메인과 고객사(R-WMS WEB) 도메인 두개의 레포지터리를 멀티레포로 따로 관리하고 있는데

    개발을 하다보니 두 도메인이 사용하는 데이터가 같고 때문에 설계되어 있는 API 로직이 90% 이상 같은 로직을 사용하고 있다.

     

    현재 각 파트에서 맡아 진행하는 업무가 있어 부득이 하게 프론트 개발을 혼자 하게되었는데

    두 가지 프로젝트에서 API 로직이 거의 같음에도 불구하고 레포지터리가 따로 관리되어 만에 하나 API 로직이 수정된다면

    수정 작업을 따로따로 해야한다는 것이 문제였다.

     

    또 자사 어드민과 고객사 도메인이 비슷한 성격의 서비스라 일반적인 어드민 페이지 처럼 일관된 UI를 사용한다는점에서도

    코드의 중복이 많아보였다.

     

    🔍 몇가지 체크를 해보자면

     

    • API 호출 경로
    • 검색폼에 사용되는 input, select 박스 UI
    • 테이블
    • API 별 에러 문구 (상수값)

     

     

    생각해보면 꽤나 많다. 우선 내가 개발을 담당하고 있으니 수정사항이 나오면 내가 불편한것도 물론이고

    나중에 혹시 모를 협업자와 이런 프로젝트 개발환경을 공유하게 된다면 얼마나 정신없이 관리가 될지 걱정이 되기 시작했다.

     

    개발자라면 이런 코드의 중복은 굉장히 거슬리기 마련..

     

     

    이런 문제들을 해결하고 싶었던 찰나 다른 회사에서 프론트개발을 하고 있던 개발자를 통해 모노레포를 도입한 경험을 들을 수 있어서

    찾아보게되었다.

     

    우선 내가 생각한 모노레포의 핵심은 따로 '분리되어있는 프로젝트내에 동일 코드를 하나로 관리해서 생산성을 높여준다' 라는 점에서

    꼭 필요한 개발환경 세팅이라 생각되었다.

     


     

    모노레포: 툴 선정

    모노레포를 사용하기로 하였으니 모노레포 툴을 선택해야하는데, 우선 모노레포의 개념과 여러 툴을 조사하는 과정에서

    고맙게도 Naver D2 포스팅에 정말 잘 정리된 모노레포 툴 소개글이 있어서 내가 사용할 툴을 선정하는데 많은 도움이 되었기에 아래 링크를 남긴다.

     

     

    모던 프론트엔드 프로젝트 구성 기법 - 모노레포 도구 편  https://d2.naver.com/helloworld/7553804

     

    내용 중 가장 세팅방법이 간단하고 현재 많은 대규모 프로젝트에서 도입하고 있는 Turborepo 를 도입하기로 하였다.

    원격 캐싱, 병렬 처리 기법 등을 통해 빌드 성능을 끌어 올리고, 쉬운 파이브라인 설정과 profiling, trace 등 다양한 시각화 기능을 제공하는 Turborepo를 선택하였다.

     

    간단하게 핵심을 알아보면

     

    npx create-turbo@latest <PACKAGE_NAME>

     

    설치 후

     

     

    모노레포의 핵심은 하나의 레포지터리 안에서 여러개의 프로젝트를 관리 할 수 있게 한다는 것이다.

    프로젝트 구성을 살펴 보면

     

    • apps: 하위에 프로젝트(어플리케이션)이 위치하게 된다.
    • packages: 공통으로 사용 할 패키지를 정의하는 구역이다.

     

    각 어플리케이션과 packages 하위에 정의된 공통 패키지들은 각각의 package.json 파일을 정의해야 한다.

    package.json 의 정의된 속성들은 나중에 명령어를 실행하거나 패키지 종속성을 연결할 식별자로 사용되는데

    마치 하나의 라이브러리 처럼 취급해서 npm을 통해 다룰수 있게 된다.

     

    위 내용대로 따라가보자면 이제 나의 프로젝트는 rwms-admin, rwms-web 두개의 레포지 터리가 아니라 하나의 레포지터리로

    관리되어야 한다.

     

    🔍 내가 해야할 작업들은 정리해보면

     

    • 멀티레포 환경을 모노레포(하나의 레포지터리) 로 다시 구성
    • 공통 패키지로 분리할 코드 선별
      • API 관련 로직 코드
      • 공통 UI 컴포넌트 코드
      • 에러 메시지 관련 상수값

     

    간단하게 이 정도로 분리하여 앞으로 개발을 이어나갈수 있겠다.

     


     

    터보레포: 공통 패키지 분리

     

     

    기본적인 모노레포 세팅 후 공통 패키지로 사용할 코드를 분리하여 작업했다.

     

    우선 Root 폴더에 위치한 package.json에서 전체 프로젝트를 install 하거나 개별적으로 workspace를 타겟팅하여 install 할 수 있다.

     

    // 전체 프로젝트 설치 스크립트
    npm install
    
    // 개별 프로젝트 설치 스크립트
    npm install -w=(workspace-name)

     

     

    전체 패키지 설치에 경우 각 폴더에 위치한 package.json의 정의에 따라 설치 된다.

    개별적으로 설치하는 경우에 workspace를 별도로 지정해서 설치를 진행하는데 해당 workspace-name은 각 프로젝트 또는 패키지 내에 존재하는 package.json의 name값을 따라간다.

     

    // root/apps/admin/package.json
    {
      "name": "admin-application",
      "version": "0.0.0",
      "main": "index.ts",
      "types": "./index.tsx",
      "license": "MIT",
      "scripts": {
        "build": "next build"
      }
      "dependencies": {
    	...
      }
    }

     

    admin 프로젝트의 package.json 파일에 정의된 name 값이 "admin-application" 이라면

     

    // 개별 프로젝트 설치 스크립트
    npm install -w=admin-application

     

    명령어로 개별 패키지 설치를 수행 할 수 있다.

     

    폴더 구성은 마쳤으니 분리된 코드를 어떻게 사용 할지가 문제다.

     

    공통으로 분리된 apis 코드를 admin 프로젝트에서 사용하기 위해선 어떻게 해야할까?

     

     


     

    터보레포: 공통 패키지 코드 import 하기

    앞서 터보레포에서 package.json에 정의 되어있는 name 을 통해 의존성을 연결하거나 패키지 관리가 가능하다고 했는데

    apis 패키지 안에도 package.json 파일을 만들어 두었다.

     

     

    // root/packages/apis/package.json
    
    {
      "name": "@package/apis",
      "version": "0.0.0",
      "main": "index.ts",
      "types": "./index.tsx",
      "license": "MIT",
      "scripts": {
        "lint": "eslint *.ts*"
      }
    }

     

    해당 파일에는 "@package/apis" 라는 이름으로 패키지의 이름을 정의했다.

    이제 가져다 쓸 차례이다.

     

    우리가 react.js 나 next.js로 개발을 할때 프로젝트의 의존성 패키지를 관리하기위해 dependencides, devDependencies에 의존성 패키지 리스트를 나열하는데 우리가 터보레포 환경에서 정의한 패키지 코드로 마찬가지로 package module 처럼 생각하고 쓰면 된다.

     

    // root/apps/admin/package.json
    
    "dependencies": {
        "@emotion/react": "^11.8.1",
        "@emotion/styled": "^11.8.1",
        "@material-ui/core": "^4.12.3",
        "@package/apis": "*",         // <-- 터보레포 환경에 정의된 apis 패키지
        "@next/bundle-analyzer": "^12.1.0",
        "@types/axios": "^0.14.0",
        "axios": "^0.26.0",
    
    // ...생략...

     

    이런식으로 설정해주면 해당 프로젝트에서 apis 에 작성된 로직을 끌어다 쓸수 있게 된다.

     

     

    실제 코드에서는 다음과 같이 Import 하여 코드를 불러온다.

     

    import Model from "@monorepo/apis/model";

    'R-WMS' 카테고리의 다른 글

    서비스 모니터링을 위한 new relic 살펴보기  (0) 2022.08.16
    react-hook-form 을 통한 쉬운 form 양식 핸들링  (0) 2022.08.07
    react-table v7 도입  (0) 2022.08.07
    프로젝트 개요와 구성  (0) 2022.08.07
    본 카테고리는  (0) 2022.07.15

    댓글

onul-hoi front-end developer limchansoo