디자인 시스템 배포에 관한 고찰 : Yarn Berry와 Turborepo 도입기

김규회·2024년 12월 13일
0

summit-up!

목록 보기
1/2
post-thumbnail

Main: https://github.com/zagdang/design-system/pull/3

새로운 프로젝트, 새로운 도전

최근 새로운 프로젝트를 시작하게 되어 디자인 시스템을 구현하게 되었다. 여기서 프로젝트에 관련된 가장 큰 고민은 서비스들이 배포한 npm을 다운받아 UI를 구성하다가 버그가 났을 때 이슈를 빠르게 수정하고 배포해야 하는 상황이었다. 팀원 또한 이것에 관하여 npm 배포보다는 오히려 서비스 내에 모노레포를 넣는 것이 어떻겠느냐라는 의견이 있었고, 이 과정에서 디자인 시스템을 분리하여 서비스 레포의 번들 사이즈를 줄이고 그 대신 배포 속도를 확실히 높인 Yarn Berry와 Turbo Repo를 택하게 되었다.

왜 Yarn Berry와 Turborepo를 선택했나?

node_modules의 구조적 문제점 상세 분석**

1. 중첩된 node_modules 구조로 인한 디스크 공간 낭비**

실제 구조 예시

node_modules/
├── react/
│   └── node_modules/
│       ├── prop-types/
│       └── loose-envify/
├── react-dom/
│   └── node_modules/
│       ├── prop-types/
│       ├── loose-envify/
│       └── scheduler/
└── next/
    └── node_modules/
        ├── react/
        │   └── node_modules/
        │       └── prop-types/
        └── webpack/

발생하는 문제

  1. 중복 설치

    • prop-types가 react, react-dom, next/react 각각의 node_modules에 설치됨
    • 동일한 패키지가 프로젝트 내에 최소 3번 이상 중복 설치
  2. 디스크 공간 계산 예시

    • prop-types 패키지 크기: 약 500KB
    • 3번 중복 설치 시: 1.5MB 차지
    • 프로젝트 전체로 보면 수백 MB의 불필요한 공간 낭비
  3. 설치 시간 증가

    • 각 중첩 레벨마다 의존성 검사 필요
    • 동일 패키지 중복 다운로드로 인한 네트워크 부하

**2. 동일 패키지의 다양한 버전 중복 설치 현상

실제 사례 예시

node_modules/
├── package-a/
│   └── node_modules/
│       └── lodash@4.17.21/
├── package-b/
│   └── node_modules/
│       └── lodash@4.17.20/
└── package-c/
    └── node_modules/
        └── lodash@4.17.19/

문제점 상세

  1. 버전 충돌

    • package-a는 lodash@4.17.21 필요
    • package-b는 lodash@4.17.20 필요
    • package-c는 lodash@4.17.19 필요
    • 결과: 동일 패키지의 서로 다른 버전이 각각 설치됨
  2. 메모리 사용량 증가

    • 각 버전별로 별도의 인스턴스 생성
    • 런타임에서 불필요한 메모리 차지
  3. 번들 사이즈 증가

    • 웹팩 같은 번들러가 각 버전을 개별적으로 번들링
    • 최종 번들 크기 증가

3. 깊은 의존성 트리로 인한 경로 길이 제한 문제

Windows 환경에서의 제한

C:\Project\node_modules\package-a\node_modules\package-b\node_modules\package-c\node_modules\package-d\node_modules\...
  1. Windows 경로 길이 제한

    • Windows의 기본 경로 길이 제한: 260자
    • node_modules 깊이가 깊어질수록 이 제한에 근접
  2. 실제 발생하는 오류 예시

    Error: ENAMETOOLONG: name too long
    • 빌드 실패
    • 패키지 설치 실패
    • 파일 접근 불가

현실적인 영향

  1. 개발 환경 문제

    // 이런 긴 경로를 가진 모듈 import 시
    import module from './node_modules/package-a/node_modules/package-b/node_modules/package-c/lib/index.js'
    • IDE에서 파일 열기 실패
    • 소스 맵 생성 실패
    • 디버깅 어려움
  2. CI/CD 파이프라인 영향

    • Windows 기반 CI 서버에서 빌드 실패
    • 배포 프로세스 중단
    • 자동화 파이프라인 불안정
  3. 해결을 위한 임시 방편

    // package.json
    {
      "scripts": {
        "postinstall": "node ./scripts/fix-windows-paths.js"
      }
    }
    • 별도의 경로 처리 스크립트 필요
    • 프로젝트 복잡도 증가
    • 유지보수 부담 가중

이러한 문제들은 프로젝트 규모가 커질수록 더욱 심각해지며, 특히 모노레포 환경에서는 그 영향이 배가된다.
디자인 시스템 내에서도 ui, icons, colors로 분리했었기 때문에 npm보다는 다른 패키지를 생각하였다.

Yarn Berry, Turbo Repo 혁신적인 선택

Yarn Berry를 첫 선택으로 한 이유

디자인 시스템을 설계할 때 가장 중요하게 생각한 부분은 '빠른 수정과 배포' 였다. 여러 서비스에서 공통으로 사용하는 컴포넌트들이다 보니, 문제가 발생했을 때 얼마나 빨리 수정하고 배포할 수 있는지가 핵심이었다.

1. Plug'n'Play의 강력한 이점

기존 node_modules 방식이 아닌 PnP 방식을 사용하면서 얻은 장점들:

  • zip 아카이브 방식으로 의존성 관리해서 설치 속도가 빨랐다
  • 프로젝트 크기가 확 줄어들어서 레포 관리가 수월했다
  • TypeScript와의 호환성이 좋아서 개발할 때 편했다

2. 모노레포 구성의 편의성

디자인 시스템을 이렇게 구성했다:

packages/
├── ui/          # shadcn 기반 컴포넌트
├── icons/       # 아이콘 컴포넌트
└── colors/      # 디자인 토큰

이렇게 나눠놓으니:

  • 각 패키지별로 독립적인 버전 관리가 가능했다
  • 한 컴포넌트만 수정해도 바로 빌드하고 테스트할 수 있었다
  • 패키지 간 의존성 관리가 깔끔했다

3. Zero-Install 시스템

협업할 때 정말 편했던 점:

  • 레포 받자마자 바로 개발 시작할 수 있었다
  • 의존성 설치 시간을 기다릴 필요가 없었다
  • CI/CD 파이프라인이 훨씬 빨라졌다

Turbo Repo 추가 도입

Yarn Berry에 Turbo Repo를 더하면서 개발 환경이 더 좋아졌다.

1. 빌드 시스템 최적화

// turbo.json
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "dev": {
      "cache": false
    }
  }
}

이렇게 설정하니:

  • 캐시 덕분에 빌드 시간이 확 줄었다
  • 변경된 패키지만 다시 빌드해서 효율적이었다
  • 다른 팀원들과 캐시를 공유할 수 있었다

2. 개발 생산성 향상

실제로 체감한 변화들:

  • 코드 수정하고 바로 결과를 볼 수 있었다
  • 테스트 실행 시간이 많이 단축됐다
  • 여러 패키지 동시 작업이 수월해졌다

실제로 좋았던 점

  1. 빠른 이슈 대응

    • 버그 발견하면 바로 수정해서 적용할 수 있었다
    • 여러 프로젝트에 동시 적용이 가능했다
    • 배포 과정이 단순해졌다
  2. 개발 환경의 일관성

    • 모든 팀원이 동일한 환경에서 개발할 수 있었다
    • 의존성 문제로 고생할 일이 없었다
    • 설정 관리가 편해졌다
  3. 퍼포먼스 향상

    • 전체적인 빌드 시간이 혁신적으로 빨라졌다.
      • 일반적으로 배포시간이 1분대내에서 전부 해결되었다.
      • test.yml, pr-check.yml파일 도 전부 40초대, 30초대로 해결되었다.
    • CI/CD 파이프라인 실행 시간도 크게 줄었다
    • 개발할 때 대기 시간이 거의 없어졌다

앞으로의 계획

지금은 기본적인 구조만 잡아놓은 상태다. 앞으로:

  • 테스트 자동화 더 강화할 예정
  • 문서화 시스템 보강
  • 빌드 최적화 더 진행할 계획

이런 구조 덕분에 디자인 시스템 운영이 한결 수월해졌다. 특히 현재 진행중인 서비스에서 동시에 사용하는 상황에서 진가를 발휘했다고 팀원들에게 긍정적인 평가를 받았다. 앞으로 더 고도화를 진행해볼 예정이다.

profile
프론트엔드 Developer

0개의 댓글