ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Monorepo (모노레포)가... 모노?
    개발 지식/CS 2023. 11. 14. 23:31

    다수의 프로젝트들이 개별적으로 운영되는 혼돈의 시대.

    레포지토리의 루트 디렉토리가 나서서 프로젝트들을 하나로 통합고, 혼돈을 가라앉히는 평화의 중심지가 되니

    이것을 우리는 모노레포의 전설이라고 부른다.

    Monorepo (모노레포)

     모노레포가 뭔지부터 알아봅시다. 흔히 정의되는 모노레포는 다음과 같습니다.

    하나의 저장소에 여러 프로젝트를 포함하는 소프트웨어 개발 전략

    Pollyrepo & Monorepo

    모노레포에 대해 설명하기 전에 폴리레포에 대해 간단히 설명하겠습니다.

    폴리레포는 여러 프로젝트를 각각 별도의 저장소에서 관리하는 소프트웨어 개발 전략입니다.

    이 방식은 프로젝트 간의 분리와 독립성을 유지하면서 개발을 진행할 수 있도록 합니다.

    하지만, 코드 간의 중복되는 부분이나 서로 다른 패키지 의존성을 관리해야 할 때 어렵다는 점이 있습니다.

     

    모노레포는 이러한 점을 해결할 수 있는 장점들이 있습니다.

    특히, 공통 부분을 상위에서 효과적으로 관리할 수 있는 점이 큰 장점 중 하나라고 생각합니다.

    이는 컨벤션과 같은 사항을 공통으로 관리함으로써 각 프로젝트의 개발자가 일관된 개발 경험을 얻을 수 있도록 합니다.

    또한, 패키지 버전을 통일하여 관리할 수 있기 때문에 프로젝트의 일관된 관리가 가능하며, 이는 프로젝트 전반적인 효율성 향상으로 이어집니다.

     

    그렇다고 모노레포가 항상 이점만 있는 것은 아닙니다.

    그러나 유사한 프로젝트를 별도로 관리하는 경우나 여러 프로젝트를 한눈에 파악해야 하는 상황에서는 모노레포가 큰 이점을 제공할 수 있습니다.

    Monorepo 적용기

    여러 프로젝트를 진행하다 보면 하나의 레포에 각각의 프로젝트를 진행하게 되는 경험이 있을 것입니다.

    저의 경우는 웹 프로젝트를 진행하는데, 서버(Backend)와 클라이언트(Frontend)로 나뉘어 진행하다 보니 그런 경험을 겪은 적이 있습니다. 

    이때, 처음 개발 환경을 구축하면서 각 프로젝트에 패키지가 각각 설치되는 문제와 공통되는 기능들을 따로 관리해야 하는 문제가 있었습니다.

    모노레포 적용 시 다른 이점도 있겠지만, 초기에 저는 이러한 문제를 해결할 수 있다는 것에 흥미를 느껴 프로젝트에 적용해보았습니다.

    Turborepo

    Turborepo는 모노레포 구축을 도와주는 도구 중 하나로  JavaScript나 TypeScript 코드를 위해 최적화된 빌드 시스템이라고 합니다.

    Turborepo는 캐싱을 통해 이전에 수행했던 동작을 건너뛸 수 있어서 빠르게 빌드가 된다는 특징이 있습니다.

    https://turbo.build/

     

    Index – Turbo

    Turbo is an incremental bundler and build system optimized for JavaScript and TypeScript, written in Rust.

    turbo.build

     

    사실 모노레포에 대한 충분한 학습을 가지지 않은 상태로 쉽게 모노레포를 구축할 수 있는 도구라고 하여 무작정 Turborepo를 이용해 보았었습니다.

    단순히 공식문서를 따라 하다 보면 금방 배울 수 있지 않을까? 라는 생각으로 시도하였지만, 설치 도중 예기치 못한 에러가 발생하기도 하고 적용이 잘 되고 있는지 저 자신도 확신하지 못하였습니다.

    복잡한 과정을 대신 해주는 점은 좋았지만, 무슨 과정인지 이해하고 있지 않다는 문제가 있어 다른 방법으로 모노레포를 적용해 보고자 하였습니다.

    하지만, Turborepo의 이점은 확실히 존재하기에 추후 적용을 시도해볼 계획입니다.

    Yarrn workspace

    현재 진행중인 프로젝트에서 모노레포를 적용할 수 있는 다른 방법들을 찾아보았습니다.

    그리고 Yarn 또는 npm의 workspaces 필드를 이용하여 모노레포를 구현하는 방법을 찾게 되었습니다.

    npm 보다는 Yarn workspace를 사용하여 모노레포를 적용한 레퍼런스들이 많고, npm에 비해 Yarn의 설치 속도가 빠른 이점이 있기에 Yarn을 이용하여 적용해보기로 하였습니다.

     

     

    1. package.json

    먼저 프로젝트들을 저장하고 있는 root에 package.json을 만들어 주었습니다.

    그리고 package.json의 workspaces 프로퍼티의 값으로 각 프로젝트 안의 package.json의 name 프로퍼티의 값을 주었습니다.

    그리고 scripts를 설정하여 root에서 각 프로젝트에 접근할 수 있도록 해주었습니다.

    // root/package.json
    {
      "workspaces": [
          "backend",
          "frontend"
      ],
      "scripts": {
        "backend": "yarn workspace backend",
        "frontend": "yarn workspace frontend"
      },
    }
    
    // root/backend/package.json
    {
      "name": "backend",
    }

    그 후 root에서 공통으로 관리할 패키지를 설치해 주었습니다. 

    저는 prettier, ESLint, TypeScript를 root에서 공통으로 관리할 수 있도록 하였습니다.

     

    2. .prettierrc, .eslintrc.js, tsconfig.json

    먼저, .prettierrc의 경우 각 프로젝트의 코드 컨벤션을 같게 해주는 것이 좋으므로 root에 위치시켜 관리할 수 있도록 하였습니다.

    .eslintrc.js의 경우에는 두 프로젝트의 공통된 부분을 root에서 관리하고, 다른 부분은 각 프로젝트에서 extends로 root의 .eslintrc.js를 받아올 수 있도록 하였습니다.

    // root/backend/.eslintrc.cjs
    module.exports = {
      extends: "../.eslintrc.js",
      ...
    }

    tsconfig.json는 두 프로젝트에서 사용하는 옵션의 공통점이 많이 없어서 우선은 따로 관리하기로 하였습니다.

     

    후기

    현재 저장소에 두 개의 프로젝트만 존재하여 간단하게만 모노레포를 적용해 보았습니다.

    아직 패키지 매니저의 다양한 기능들에 대해 잘 파악하지 못하여 조금 더 효율적으로 공통 모듈을 관리하지 못한 것 같아 아쉬움이 남습니다.

    또한, 아직은 프로젝트 간의 의존성이 크게 없어서 모노레포의 장점을 잘 활용할 수 없다고 생각합니다.

    그래도 각 프로젝트에서 공통으로 사용하는 기능들을 한 번에 관리할 수 있다는 이점이 있어 만족하고 있습니다.

    이후 진행하면서 점검을 통해 조금씩 개선을 해나갈 계획입니다.

     

    참고

    https://d2.naver.com/helloworld/0923884

    https://d2.naver.com/helloworld/7553804

    https://www.testbank.ai/42b54c4b-2aa7-4bc7-b29b-b7219c700f22

Designed by Tistory.