라이브러리 게시

적절한 도구를 사용하면 모노레포에서 npm 레지스트리에 패키지를 게시하는 것이 원활한 경험이 될 수 있습니다.

이 가이드는 견고한 패키지에 필요한 모든 가능한 컴파일, 번들링 및 게시 설정을 해결할 수는 없지만 몇 가지 기본 사항을 설명합니다.

모노레포의 일부 패키지를 npm에 게시하려는 경우 이 설정을 따라야 합니다. npm에 게시할 필요가 없다면 Internal Package를 사용해야 합니다. 설정 및 사용이 훨씬 쉽습니다.

번들링

Internal Packages와 달리 외부 패키지는 npm에 배포하고 로컬에서 사용할 수 있습니다. 이 가이드에서는 npm에서 가장 일반적으로 사용되는 형식인 ECMAScript modules(esm)과 CommonJS modules(cjs) 모두에 패키지를 번들링합니다.

빌드 스크립트 설정

Internal Packages 튜토리얼을 사용하여 생성된 패키지부터 시작하겠습니다.

거기서 숫자를 더하고 빼는 몇 가지 도우미 함수가 포함된 @repo/math 패키지를 만들었습니다. 이 패키지가 npm에 충분히 좋다고 판단하여 번들링할 것입니다.

번들러를 사용하여 @repo/mathbuild 스크립트를 추가할 것입니다. 어떤 것을 선택해야 할지 모르겠다면 tsup를 권장합니다.

패키지 매니저를 사용하여 ./packages/math 패키지 내에 tsup를 설치한 다음 빌드 스크립트를 만듭니다:

./packages/math/package.json
{
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts"
  }
}

tsup는 기본적으로 dist 디렉토리에 파일을 출력하므로 다음을 수행해야 합니다:

  1. .gitignore 파일에 dist를 추가하여 소스 제어에 커밋되지 않도록 합니다.
  2. turbo.jsonbuild outputs에 dist를 추가합니다.
Turborepo logo
./turbo.json
{
  "tasks": {
    "build": {
      "outputs": ["dist/**"]
    }
  }
}

이렇게 하면 tsup가 실행될 때 출력이 Turborepo에 의해 캐시될 수 있습니다.

마지막으로 패키지 진입점을 업데이트해야 합니다. package.json 내에서 CommonJS modules(cjs)를 사용하는 클라이언트를 위해 main./dist/index.js로, ECMAScript modules(esm)를 사용하는 클라이언트를 위해 module./dist/index.mjs로, 타입 정의 파일인 ./dist/index.d.ts를 위해 types를 변경합니다:

./packages/math/package.json
{
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts"
}

cjsesm 모두에 번들링할 필요는 없습니다. 그러나 권장되는데, 이를 통해 패키지를 다양한 환경에서 사용할 수 있습니다.

main, moduletypes를 사용하여 오류가 발생하면 tsup docs를 참조하세요.

번들링은 복잡한 주제이며 여기서 모든 것을 다룰 공간이 없습니다!

앱 전에 패키지 빌드

turbo run build를 실행하기 전에 고려해야 할 사항이 하나 있습니다. 모노레포에 작업 종속성을 추가했습니다. packages/mathbuildapps/webbuild 전에 실행되어야 합니다.

다행히도 dependsOn을 사용하여 이를 쉽게 설정할 수 있습니다.

Turborepo logo
./turbo.json
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"]
    }
  }
}

이제 turbo run build를 실행하면 앱을 빌드하기 전에 패키지를 자동으로 빌드합니다.

dev 스크립트 설정

설정에 작은 문제가 있습니다. 패키지를 잘 빌드하고 있지만 개발에서 제대로 작동하지 않습니다. @repo/math 패키지에 대한 변경 사항이 앱에 반영되지 않습니다.

작업하는 동안 패키지를 다시 빌드할 dev 스크립트가 없기 때문입니다. 쉽게 추가할 수 있습니다:

./packages/math/package.json
{
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts",
    "dev": "tsup src/index.ts --format cjs,esm --dts --watch"
  }
}

이렇게 하면 --watch 플래그가 tsup에 전달되어 파일 변경 사항을 감시합니다.

turbo.json에서 이미 dev scripts를 설정한 경우 turbo run dev를 실행하면 packages/math dev 작업이 apps/web dev 작업과 병렬로 실행됩니다.

이제 패키지가 npm에 배포할 수 있는 상태입니다. 버전 관리 및 게시 섹션에서 바로 그렇게 할 것입니다.

버전 관리 및 게시

모노레포에서 패키지를 수동으로 버전 관리하고 게시하는 것은 지루할 수 있습니다. 다행히도 작업을 쉽게 만드는 도구가 있습니다 - Changesets CLI입니다.

Changesets는 직관적으로 사용할 수 있고 Turborepo처럼 이미 익숙한 모노레포 도구와 잘 맞기 때문에 권장합니다.

몇 가지 대안은 다음과 같습니다:

  • intuit/auto - 풀 리퀘스트의 시맨틱 버전 레이블을 기반으로 릴리스 생성
  • microsoft/beachball - The Sunniest Semantic Version Bumper

게시

패키지가 번들링되면 npm 레지스트리에 게시할 수 있습니다.

Changesets 문서를 살펴보는 것을 권장합니다. 다음은 권장 읽기 순서입니다:

  1. Why use changesets? - 기본 사항을 안내하는 소개
  2. Installation instructions
  3. GitHub를 사용하는 경우 Changeset GitHub bot 사용을 고려하세요 - PR에 changesets을 추가하도록 유도하는 봇입니다.
  4. Changesets GitHub action 추가도 고려해야 합니다 - 게시를 매우 쉽게 만드는 도구입니다.

Turborepo와 함께 Changesets 사용

Changesets 사용을 시작하면 세 가지 유용한 명령에 액세스할 수 있습니다:

Terminal
# 새 changeset 추가
changeset
 
# 패키지의 새 버전 생성
changeset version
 
# 변경된 모든 패키지를 npm에 게시
changeset publish

게시 플로우를 Turborepo에 연결하면 배포를 훨씬 간단하고 빠르게 구성할 수 있습니다.

Changesets가 changeset version의 변경 사항을 자동으로 커밋하도록 설정하는 것이 좋습니다.

./.changeset/config.json
{
  // …
  "commit": true
  // …
}

그리고 루트 package.jsonpublish-packages 스크립트를 추가합니다:

./package.json
{
  "scripts": {
    // 게시 전에 실행해야 하는 모든 것 포함 - build, lint, test
    "publish-packages": "turbo run build lint test && changeset version && changeset publish"
  }
}

패키지가 public인 경우 Changeset의 accesspublic으로 설정합니다:

./.changeset/config.json
{
  // …
  "access": "public"
  // …
}

npm의 내장 publish 스크립트와 충돌하지 않도록 publish-packages를 권장합니다.

즉, publish-packages를 실행하면 모노레포가 빌드, 린팅, 테스트 및 게시되며 Turborepo의 모든 속도 향상 혜택을 받을 수 있습니다.