Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

모노레포에 대한 이해 #2

Open
ed-jinyoung-park opened this issue Jul 14, 2023 · 8 comments
Open

모노레포에 대한 이해 #2

ed-jinyoung-park opened this issue Jul 14, 2023 · 8 comments

Comments

@ed-jinyoung-park
Copy link
Collaborator

ed-jinyoung-park commented Jul 14, 2023

목차

  1. 모노레포란?
  2. Why monorepo?
  3. 모노레포 전반적인 기능
  4. 세부 비교 (사례와 함께 + 특징, 장단점)
    1. Yarn workspace
    2. Lerna
    3. Nx
    4. Turborepo
  5. 마무리, 후기

중점

  • 어떤 모노레포를 어떤 프로젝트에 쓰면 좋은지
  • 마이그레이션 가능?

레퍼런스

@ed-jinyoung-park
Copy link
Collaborator Author

ed-jinyoung-park commented Jul 15, 2023

모노레포란?

image
  • 하나의 repository안에서 다양한 프로젝트들을 관리
    • ex) app1, app2, lib1, lib2...
  • 각 프로젝트들이 서로 의존성을 가져 코드를 공유할 수 있다.
    • ex) app1이 lib1, lib2에 의존성을 가짐. app2는 lib3에 의존성을 가짐. lib2는 lib3에 의존성을 가짐.
  • 모노레포는 모놀리식의 한계로부터 출발한다.

모놀리식(monolith)

image

  • monolith는 모듈화 없이 설계된 소프트웨어 어플리케이션
  • 하나의 코드 베이스로 모든 프로젝트를 관리
  • 한번 change를 만들면 모든 프로젝트를 rebuild, retest해야함. (CI/CD pipeline이 하나)
  • 어플리케이션 종속성 관리가 어려움 (관심분리가 어렵다)

모듈화(modular)

image

  • 모놀리식 구조가 가진 한계를 해결한 구조
  • 관심분리가 가능
  • 로직을 재사용하기에 용이해짐

멀티레포(multirepo 혹은 polyrepo)

image

  • 모놀리식의 모듈을 다른 어플리케이션에서도 사용하기 위해 나온 구조.
  • 각 팀, 어플리케이션, 프로젝트마다 repo를 가지는 형태.
  • 독립적인 개발, 린트, 테스트, 빌드, 배포 파이프라인이 존재
  • 각 팀의 자율성과 관리 측면에서 polyrepo를 도입해으나 다음과 같은 한계가 있다.
    • 프로젝트 생성에 비용이 많이 듬 : repo간 코드 공유를 하기 위해서는 새로운 shared repo를 만들어야 하고 여러가지 setup을 해야하는 등 비용이 많이 든다.
    • 패키지의 중복 코드 가능성 : 따라서 아무도 shared repo를 만들려 하지 않고 각 팀에서 각자 공통 서비스나 컴포넌트를 만들어 코드 중복이 많이 생긴다. 이는 곧 부채가 된다.
    • 다른 패키지의 변경 사항 파악 어려움 : shared library를 만든다고 하더라도 revision history가 연결되어있지 않아 breaking change 등이 있을 때 히스토리 추적이 어렵다.
    • 일관성 없는 개발자 경험 : build, test, lint, deploy, serve 등이 일관되지 않아 관리포인트가 증가한다.

monorepo

image

  • 두 개 이상의 프로젝트가 동일한 저장소에 저장되는 전략. 각 프로젝트는 서로 관계를 지니고 있음.
  • monorepo는 이를 이렇게 해결한다.
    • 쉬운 프로젝트 생성 : 새로운 프로젝트는 기존에 존재하는 CI setup으로 적은 비용으로 쉽게 만들 수 있다.
    • 프로젝트들간 커밋을 공유 : 다른 프로젝트의 변경사항에 쉽게 대비할 수 있다.
    • 쉬운 의존성 관리 : 패키지가 같은 저장소에 있어 패키지 관리가 용이
    • 일관된 개발자 경험 : build,test 방법이 일관되기 때문에 관리포인트가 감소한다.

frontend에서 monorepo가 적절한 사례

  • service별, module(component, hooks, api)등으로 �프로젝트를 분리하기에 용이한 경우
  • device별로 project를 구분하고 data layer(상태관리)등은 shared library로 사용
    • app-mobile, app-desktop, app-data
  • framework별로 제공되는 libraray가 필요할 경우
    • app-core, app-react, app-vue, app-svelte
  • bff를 써서 server까지 같이 개발해야 할 경우
    • app-server, app-client
  • core libraray가 있고 이를 플러그인으로 확장할때
  • 유사한 devops로 구성된 프로젝트
    • lint, test, build, deploy가 유사한 경우

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

모노레포 전반적인 기능

1. Local computation caching 로컬에서 계산할 내용 캐싱

  • 로컬 캐싱: 같은 머신에서 같은 것을 두 번 빌드하거나 테스트하지 않습니다.
  • 이미 빌드된 내용은 건너 띕니다.

아래는 터보의 예시입니다. 빌드를 할 때, 이미 빌드된 내용을 건너 띄어 빠르게 작업할 수 있습니다.
Screen Shot 2023-07-18 at 2 24 46 AM

2. Local task orchestration

  • 로컬 작업 오케스트레이션: 빌드 및 테스트 등의 작업을 순서에 맞게 병렬로 실행

모든 코어를 사용하는 병렬 실행을 목표로 합니다. 지정된 태스크 단위로 의존성을 판단해 최대한 병렬적으로 작업을 진행합니다.
Screen Shot 2023-07-18 at 2 31 40 AM

3. Distributed computation caching

  • 분산 캐싱: 다양한 환경에서 캐시 아티팩
    트를 공유합니다. 즉, 조직 단위로 여러 CI 환경에 걸쳐 같은 것을 두 번 빌드, 테스트하지 않음
Screen Shot 2023-07-18 at 11 17 15 AM

4. Distributed task execution

  • 분산 작업 실행: 단일 시스템에서 실행되어 여러 시스템에 명령을 전달
Screen Shot 2023-07-18 at 11 17 59 AM

5. 영향을 받는 프로젝트/패키지 감지(Detecting affected projects/packages)

  • 변화에 영향을 받는 프로젝트 감지: 변경의 영향을 받을 수 있는 항목을 결정하여 영향을 받는 프로젝트만 빌드/테스트

6. Dependency graph visualization

의존성 그래프 시각화: 프로젝트 및 작업 간의 종속 관계를 시각화

예시 - NX의 Dependency graph
Screen Shot 2023-07-18 at 11 18 38 AM

Screen Shot 2023-07-18 at 11 20 10 AM

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

모노 레포 툴 세부 비교

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

npm/yarn workspace

  • Yarn(1.x) / Yarn berry / npm(7.x 이상)에서  workspaces 필드를 이용하여 모노레포를 구성 가능. 
  • npm, yarn 자체 내장되어 있는 기능이라 러닝 커브가 낮다.
  • Yarn berry를 같이 사용하는 경우가 많은데, 이를 이용할 경우 패키지의 의도하지 않은 호이스팅을 허용하지 않을 수 있는 장점이 있다.
  • 기능 자체는 많이 제공하지 않는다.

Lerna

  • lerna를 사용하여 node module을 설치할 경우 자체적으로 패키지들의 모듈을 설치하고, 그 과정에서 종속성을 관리하여 중복된 모듈을 하나로 통합합니다.
  • 모듈 간의 의존성 관리하여 모듈 간의 충돌을 방지하고, 모듈을 더 쉽게 관리할 수 있습니다.
  • 모듈을 병렬로 빌드하여 빌드 시간을 단축할 수 있습니다.
  • 여러 개의 모듈 혹은 Package에 대해 하나의 버전 혹은 독립적인 버전을 가져갈 수 있습니다.
  • 변경된 패키지를 Github Repository에 Push할 때나 NPM Publish할 때, 한번에 처리할 수 있습니다.
  • nx에서 인수하여 nx cloud를 이용한 여러 기능들을 사용 가능합니다.

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

nx

  • 구글 출신 개발자들이 만든 모노레포 툴 (https://nx.dev/)
  • 분산 작업 실행, 빌드시 computation caching 제공
  • 프로젝트 상황에 따라 setup guide를 제공
    • Package-Based Repos : pacakge 기반 프로젝트. 각 package가 다른 버전을 가짐.
    • Intergrated Repos : 각 package가 같은 single version을 가짐. 기본 tool이 setup된 형태로 제공
    • Standalone Applications : 기존 react, angular 등의 프로젝트에 nx tool만 도입
  • 코드 수정시 어떤 부분이 영향받았는지 알려주는 affected 명령어 제공
    image
  • 프로젝트간 dependency를 시각화하여 보여주는 project graph 기능을 제공
    image
  • vscode 내 nx console 통합 기능 제공
image - 다른 프로젝트, 라이브러리들을 nx에 적용할 수 있는 plugin 생태계가 활발 image - nx cloud라는 별도 CI/CD sass 제공

Turborepo

  • Vercel에서 개발한 JS/TS를 위한 모노레포 빌드 시스템
  • Vercel에서 만들었기 때문에 기본 셋은 Next.js로 제공
  • Zero config를 지향
  • nx와 동일하게 원격 캐싱, 병렬 처리 등으로 빌드 성능 향상
    • 가장 핵심 원칙은 "이미 계산한 것들은 다시 계산하지 않는다"
  • 병렬 작업 처리가 어떤 순서로 얼마나 걸리는지 chrome performance 탭에서시각화해서 볼 수 있는 profile 기능 제공
    image

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

마무리, 후기

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

yarn workspace 실제 후기

Yarn workspace + yarn berry

/scripts - static (css,  )   /  빌드 배포 관련 
/settings - workspace 설정, eslint, prettier, husky 
/packages
 common(공통)
 플젝 A
 플젝 B
 플젝 C
 플젝 D
   ngnix, docker  배포 관련
   src
     common
     components
     pages
   public
   msw - test

도입하게 된 계기

비슷한 내용과 스펙을 가지고 관리 주체가 같은 프로젝트들을 묶기 위하여 도입하였습니다.
따라서 빌드 시간 단축 등 다른 기능들의 장점이 필요하지 않아서 가장 간단하게 사용할 수 있는 yarn workspace + yarn berry를 채택하였습니다.

실제 사용했을때 장점

  • 가장 큰 장점은 관리 포인트가 줄어든 것이었습니다.
  • 여러 프로젝트를 하나의 github repo에서 관리할 수 있다.
  • 초기 세팅은 시간이 좀 걸려도, 새로운 프로젝트를 추가할 때 빠르게 추가할 수 있다.
  • 코드 변경, 배포, 릴리즈 노트 등을 하나에서 볼 수 있다는 것이 장점이었습니다.
  • 또한 러닝 커브가 낮다는 것도 큰 장점이었습니다.
  • 별다른 세팅이나 설치 없이 사용할 수 있었습니다.

실제 사용했을때 단점 및 고려 사항

  • 공통에는 무엇을 담아야할지?

    • 처음에는 모든 프로젝트에서만 사용하는 내용만 담으려했지만, 코드의 중복이 심해져 두 개 이상이면 담았다.
    • 하지만 이렇게 되면, 플젝 내에서의 공통(common)을 관리 + 플젝끼리의 공통을 관리하는 두 가지 번거로움이 생겼습니다.
    • 프로젝트가 커지다보니 공통 혹은 중복되는 코드를 찾기가 힘들다는 것이 단점이었던 것 같습니다.
  • 버전 관리의 문제

    • 하나의 github repository에서 관리하기 때문에 커밋 양도 많아지고, github release note를 작성하다보면, 그 내용 또한 많아졌습니다.
    • 규칙을 정한다면 어느 정도 해결될 문제이지만, 하나의 프로젝트가 아닌 여러 개의 프로젝트가 생겨 어느 정도의 난잡함이 생긴다.
    • 또한 특정 프로젝트 혹은 레포의 내용을 찾아보려면 필터링을 한번 해야한다는 수고로움이 생깁니다.
  • [추가] yarn berry 문제 → 생각보다 짜잘짜잘한 버그가 많다. 특히 패키지 캐싱이 이상하게 되는 경우가 있어서 문제가 있다.

    • 캐싱 때문에 패키지 업그레이드를 해도 안먹는 케이스가 있다.
    • 패키지 버전은 그대로인데, 가끔 해싱 값이 변경되버려서 불필요한 파일 변경이 생길 때가 있다.

@puba5
Copy link
Collaborator

puba5 commented Jul 16, 2023

NX 실제 후기

폴더 구조

apps - 어플리케이션
  ㄴ demo
  ㄴ docs
libs - 라이브러리. core를 기준으로 plugin을 확장해나가는 형태
  ㄴ core
  ㄴ plugin A
  ㄴ plugin B ..
tools - nx tool
nx.json
package.json
...

도입하게 된 계기

  • 핵심 코어 로직과 이를 기반으로 여러가지 피쳐들을 플러그인 형태로 개발해야 하는 프로젝트
  • 코어, 플러그인들의 버전들을 하나의 레포에서 관리하고 CI/CD도 일관되게 가져갈 수 있는 형태
  • 빠른 플러그인 개발, dependency 관리, 빌드 효율화 등도 중요한 이슈 중 하나이기에 다소 러닝커브가 있지만 모노레포 툴로써의 다양한 기능을 지원하는 nx를 선택

장점

  • nx cli가 굉장히 잘 되어 있다.
    • nx:library:new ${libraryName}
    • nx:build
    • nx:test
    • nx:serve ${appName}
  • 라이브러리, app을 이동하면서 동시에 개발하기 용이하다.

단점 및 한계

  • 러닝커브가 있다.
    • tools에 대한 이해 및 커스터마이징
  • npm, yarn, pnpm을 모두 지원한다고 나와있지만 기본 preset인 npm에 최적화되어 있는 것 같다.
  • 순환참조 문제
    • lib:a<->lib:b 간 서로 참조하는 문제

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants