Turborepo 세팅

GwangSoo·2024년 11월 14일

졸업작품

목록 보기
2/4
post-thumbnail

지난 글에서는 크롬 익스텐션에서 소셜 로그인을 하는 방법에 대해 알아보았다.

이번에는 모노레포의 종류 중 하나인 Turborepo에 대해서 알아보고, 왜 졸업 작품에서 모노레포 방식을 사용하게 되었는지 이야기를 해보고자 한다.

모노레포를 선택한 이유

우리 팀은 졸업 작품으로 크롬 익스텐션과 웹 애플리케이션 총 2개를 만든다.

처음에는 레포지토리를 2개를 생성하여 멀티 레포 구조를 가져가려 했다.

하지만 개발을 하다 보면 익스텐션의 UI와 웹의 UI에서 중복으로 사용되는 컴포넌트가 나올 것이고, DTO 및 기타 타입 등이 겹치게 될 것이다.

이를 2개의 레포지토리에서 따로 관리를 하게 된다면 컴포넌트 혹은 타입의 수정이 필요할 때 2개 모두 일일이 수정해야 한다는 번거로움이 있다.

따라서 모노레포를 도입하여 진행하기로 했다.

모노레포란?

모노레포하나의 레포지토리에서 여러 개의 프로젝트를 관리할 수 있는 방식을 의미한다.

그렇다면 모노레포를 사용하면서 얻을 수 있는 이점으로는 뭐가 있을까?

1. 코드 공유 및 재사용성 증가

위에서도 언급했듯이 공통으로 사용되는 util, hook 등을 효율적으로 관리할 수 있게 된다.

2. 일관된 개발 환경 유지

Typescript, eslint 등을 동일한 버전으로 사용함으로써 동일한 개발 환경을 유지할 수 있다.

3. 협업 및 코드 품질 향상

하나의 레포지토리에서 관리가 되기 때문에 코드 컨벤션 및 테스트를 일관되게 유지할 수 있다.

특히 1, 2번의 이점으로 멀티레포가 아닌 모노레포를 선택하게 되었다.

Turborepo를 선택한 이유

모노레포도 종류가 여러 가지 있는데 이 중에서 Turborepo를 선택한 이유에 대해 이야기해보겠다.

1. 간단한 설정

다른 모노레포인 Nx에 비해 설정 및 사용이 간단하고 공식 문서에 다양한 examples가 있어서 필요에 맞게 갖다 쓰거나 참고해서 쓰기 좋았다.

2. Vercel과의 통합

Turborepo는 Vercel에서 제작했기 때문에 원격 캐싱 혹은 Vercel에서 제공하는 다양한 기능들을 쉽게 사용할 수 있다.

설정하며 만난 오류

type 자동 완성 추천 ❌

🚨 문제 상황

처음 폴더 구조는 아래와 같았다.

apps
|_extension
|_www
packages
|_types
|__example.ts
|__index.ts
|__package.json
// example.ts
export interface Example {
  name: string;
  age: number;
}
// index.ts
export type * from "./example";
// package.json
{
  "name": "@repo/types",
  "exports": {
    "types": "./index.ts"
  }
}

wwwextensiondevDependencies“@repo/types”: “workspace:*”를 명시하고 pnpm install을 하여 Example 타입을 가져오려 했는데, 자동 완성에 나오지 않았다.

example-1

직접 import하려 해도 아래와 같은 에러가 나왔다.

example-2

🔍 해결 과정

tsconfig.jsoncompilerOptions 옵션에 types 필드를 추가하여 @repo/types를 컴파일 목록에 추가하였다.

{
  "compilerOptions": {
    "types": ["@repo/types"]
  },
}

types 필드에 대해 간단하게 알아보겠다.

  • types 필드가 없다node_moduels/@types를 자동으로 컴파일 목록에 포함시킨다.
  • types 필드에 빈 배열을 넣게 되면 @types 패키지는 무시되게 된다.
  • types 필드에 명시한 라이브러리의 @types들만 컴파일 목록에 포함시키고 나머지는 컴파일 목록에서 제외한다.

컴파일 목록에 포함되게 되면 전역 스코프로 들어가게 되어 자동 완성 추천에 나오게 된다.

이후 폴더 구조와 package.json의 내용을 아래와 같이 바꿨다.

apps
|_extension
|_www
packages
|_types
|__dist
|__src
|___example
|____index.ts
|___index.ts
|___package.json
// package.json
{
  "name": "@repo/types",
  "scripts": {
    "build": "tsc"
  },
  "exports": {
    "types": "./dist/index.d.ts"
  }
}

pnpm build를 이용하여 dist/index.d.ts를 생성 후 apps 패키지에서 Example 타입을 입력하니 자동 완성 추천이 정상적으로 되었다.

example-3

type 수정 실시간 반영 ❌

🚨 문제 상황

types 패키지에서 새롭게 추가하거나 수정한 내용들이 개발 시 실시간으로 반영되지 않는 것을 확인했다.

🔍 해결 과정

watch라는 옵션을 달아주어 type에 변경이 생기면 바로 반영이 되도록 수정했다.

또한 개발 서버와 tsc —watch를 같이 실행시키기 위해 root의 package.json에 스크립트를 추가해 주었다.

// package.json
{
  "scripts": {
    "dev": "turbo dev", // www, extension, tsc 모두 실행
    "dev:extension": "turbo dev --filter=extension --filter=@repo/types", // extension, tsc 실행
    "dev:www": "turbo dev --filter=www --filter=@repo/types", // www, tsc 실행
  },
}
// packages/types/package.json
{
  "name": "@repo/types",
  "scripts": {
    "dev": "tsc --watch"
  },
  "exports": {
    "types": "./dist/index.d.ts"
  }
}

마무리하며

모노레포 세팅을 처음부터 끝까지 해보는 것이 처음이라 많이 어려웠다.

tsconfig.json의 동작 방식, package.json의 필드에 대한 개념이 부족하다고 느끼게 된 계기가 되었다. 하지만 그만큼 얻어 가는 것도 많았던 것 같다.

참고

0개의 댓글