pnpm workspace, turborepo

pnpm, turborepo

pnpm

  • 여러 애플리케이션, 패키지를 한 저장소에서 설치, 연결
    • 가령, 앱 foo가 공유 패키지 bar에 의존한다고 선언하면 공유 패키지로 있는 bar를 사용하게 함
    • 공통 lockfile을 관리하고, 패키지간 의존 관계를 고려해 빌드 스크립트를 실행하거나, 특정 패키지만 선택할 수도 있음 (cf. pnpm -r build)
  • Node.js 패키지 매니저 — 의존성 해결·설치·버전 관리와 저장 공간의 효율화가 주안점

Workspace

  • 여러 프로젝트를 하나의 저장소에서 관리하며, 프로젝트 간 로컬 의존성을 연결하고 명령을 실행할 수 있도록 지원
    • ‘어떤 프로젝트들을 하나의 모노레포로 묶을 것인가?’
  • pnpm이 모노레포를 지원하는 방식 — 여러 패키지를 하나의 작업 공간으로 연결, 관리
# apps와 packages 아래의 프로젝트들은 각각 독립적인 패키지이면서,
# 동시에 하나의 Workspace에 속한다.
packages:
  - "apps/*"
  - "packages/*"
  • 기능
    • 내부 패키지 참조 : 각 애플리케이션이 공유 패키지를 로컬 의존성으로 사용할 수 있음
    • 통합 의존성 관리 : 루트의 pnpm install로 전체 패키지 설치
    • 공유 lockfile : 기본적으로 루트의 pnpm-lock.yaml 하나로 버전 관리
    • 선택적 명령 실행 : pnpm --filter @foo/api build 처럼, 특정 패키지만 실행 가능
      • workspace:* 프로토콜 사용 시, 해당 의존성이 반드시 로컬 Workspace에서 해결되도록 강제 가능 → 같은 모노레포에 있는 다른 패키지를 의존성으로 사용할 때 선언
        {
          "name": "@foo/app",
          "dependencies": {
        	  // @bar/types는 npm에서 내려받지 말고, 반드시 현재 Workspace 내부에서 찾아 연결할 것
            "@bar/types": "workspace:*",
            "next": "^16.0.0"
          }
        }

Turborepo

  • 의존성 관계를 파악해서 공유 패키지를 먼저 빌드하고, 이후 독립적인 앱 빌드를 병렬로 진행한다던가를 가능케함
    • 소스 코드와 관련 input이 변경되지 않았다면 — 기존 결과를 캐시에서 복원하여 불필요한 빌드를 생략 가능 (작업 입출력, 환경 변수 등 구성 필요)
    • 공유 패키지가 늘고, CI의 중복 빌드가 부담스러워지면 Turborepo의 캐싱과 작업 그래프가 효과적
  • 패키지들이 수행하는 작업의 실행 순서, 결과 재사용 최적화에 주안점

빌드 캐시

  • 다음 빌드에서 입력이 같다면 — 컴파일을 또 하는 대신, 이전 작업 산출물을 다시 가져오는 것
    • 빌드 : dist, .next 등의 산출물
    • 테스트·린트 : 작업 실행 결과 및 로그
    • 캐시할 파일은 turbo.json의 outputs로 명시해야 함
    • 입력에는 소스 코드뿐 아니라 패키지 의존성, 설정, 관련 환경변수 등이 포함될 수 있음
  • Turborepo는 입력을 비교할 식별값을 만듦 — 일치하는 결과가 있으면 복원
    • 공유 패키지처럼 애플리케이션이 사용하는 코드를 수정하면, 입력이 달라지므로 다시 빌드
  • 공유 패키지처럼 애플리케이션이 사용하는 코드를 수정하면, 입력이 달라지므로 다시 빌드
  • pnpm의 다운로드 캐시와 다름
    • pnpm은 패키지를 다시 다운로드하는 시간을 줄일 수 있음
    • 하지만 그것만으로 애플리케이션의 컴파일을 건너뛰지는 않음
    • CI가 매번 새 컴퓨터에서 실행된다면, 이전 빌드 결과를 재사용하기 위해 원격 캐시, 혹은 CI 캐시 저장소 필요
  • pnpm은 패키지를 다시 다운로드하는 시간을 줄일 수 있음
  • 하지만 그것만으로 애플리케이션의 컴파일을 건너뛰지는 않음
  • CI가 매번 새 컴퓨터에서 실행된다면, 이전 빌드 결과를 재사용하기 위해 원격 캐시, 혹은 CI 캐시 저장소 필요