ShimYuseob

    Turborepo로 모노레포 구성하기

    개인 블로그 레포지토리 turbo와 pnpm으로 터보레포 마이그레이션하기
    2023.12.220 views

    나는 Dudum이라는 영상제작 매칭 플랫폼 서비스를 운영하고 있는 스타트업에 재직중이고, 개발환경은 next.js 프레임워크를 사용하고있다.

    영상을 활용하는 두둠 서비스의 방대한 데이터를 활용할 수 있는 스톡 서비스(포스팅을 옮기는 시점에서는 이미 Dropshot Stock이라는 서비스명으로 런칭했다.) 런칭을 기획중이고 스톡 서비스의 환경을 어떻게 구성할지에 대한 아젠다가 있어 관련 아티클을 찾아보게 되었다.

    기본적으로 내장된 webpack보다 빌드 시간을 40% ~ 85% 까지 개선할 수 있는 turbopack을 알게되었고, 마침 새로운 서비스에 적용할 수 있겠다는 생각이 들어 개발팀 주간리뷰 회의 안건으로 Using Turborepo to Build Your First Monorepo 아티클을 가져왔다.

    이후 패키지 매니저를 yarn에서 pnpm으로 전환해야 하는 이유에 대해서는 설득했으나 turborepo로 전환하는 작업까지는 여러 이유로 진행하지 못해서 개인 프로젝트에서 진행해보게 되었다.


    기존 프로젝트에서는 텍스트편집기 패키지와 supabase를 통해 학습용 블로그를 만들었었는데 mdx를 활용한 포스팅도 해볼까? 하다 같은 레포 내에서 모노레포를 구성해봐도 좋을 것 같았다.

    아래는 기존 프로젝트 트리인데, 개인 프로젝트에선 패키지 매니저를 pnpm을 사용하고 있었고, turborepo를 구성할 때 주로 사용하는 appspackages로 분리하는 구조를 따라가기로 했다.

    터보레포 마이그레이션 전 디렉토리 구조
    ./
    ├── README.md
    ├── components.json
    ├── next-env.d.ts
    ├── next.config.mjs
    ├── node_modules
    ├── package.json
    ├── postcss.config.mjs
    ├── prisma
    ├── public
    ├── src
    │    ├── app
    │    ├── components
    │    ├── constants
    │    ├── fonts
    │    ├── lib
    │    ├── providers
    │    ├── services
    │    ├── types
    │    └── utils
    ├── tailwind.config.ts
    └── tsconfig.json

    우선 공식문서를 보고 기존 레포지토리를 마이그레이션하는 방법으로 진행해보기로 했다.

    1. turbo 패키지 설치 및 디렉토리 구조 변경#

    turbo 패키지 설치 방법
    # Global install
    pnpm add turbo --global
     
    # Install in repository
    pnpm add turbo --save-dev

    turborepo를 적용하려면 기본적으로 turbo가 설치되어 있어야 한다.

    turbo를 설치하고 디렉토리 구조를 아래와 같이 변경 후, 기존 root에 있던 모든 파일을 apps/web 으로 이주했다.

    터보레포 디렉토리 구조
    ./
    ├── apps
    │    ├── blog
    │    └── web
    ├── packages
    └── turbo.json

    2. json 파일추가 및 workspace 설정#

    이주 후 root 경로에 turbo.json을 추가하고 package.json도 추가하자.

    turbo.json
    {
      "$schema": "https://turbo.build/schema.json",
      "tasks": {
        "build": {
          "dependsOn": ["^build"],
          "outputs": [".next/**", "!.next/cache/**"]
        },
        "check-types": {
          "dependsOn": ["^check-types"]
        },
        "dev": {
          "persistent": true,
          "cache": false
        }
      }
    }
    package.json
    {
      "private": true,
      "scripts": {
        "build": "turbo run build",
        "dev": "turbo run dev",
        "lint": "turbo run lint"
      },
      "devDependencies": {
        "turbo": "latest"
      },
      "packageManager": "pnpm@9.0.0"
    }

    다음으로 root 경로에 워크스페이스를 추가한다. 나는 pnpm을 사용하고 있어서 pnpm 방법으로 설정했다. 본인이 사용하고 있는 패키지에 맞게 설정하면 된다.

    pnpm-workspace.yaml
    packages:
      - 'apps/*'
      - 'packages/*'

    끝났다. 이제 node_modules와 lock파일을 삭제하고 root 경로에서 pnpm i 를 통해 패키지를 재설치 하면된다. .gitignore에 .turbo를 추가하는것도 잊지말자.

    나는 apps/ 하위에 이주한 web과 blog를 root 경로에서 편하게 실행하기 위해 script를 추가했다.

    package.json > script
    {
      "script": {
        "web": "turbo --filter web",
        "blog": "turbo --filter blog"
      }
    }

    추가적으로 기존 프로젝트에서 husky와 prisma를 사용했었는데, 폴더를 그대로 옮기다가 초기 설치 경로에 설정된 파일들의 위치와 현재 위치가 불일치하여 오류가 발생했다.

    에러 메시지는 아래와 같이 나왔다.

    . prepare$ husky │ .git can't be found

    구글 서칭을 해보니 Husky 디렉토리까지 통채로 옮겨서 발생한 문제였다. Husky가 실행 가능한 구조가 package.json 파일과 .git 디렉토리가 같은 레벨에 있어야 하는데 위치가 맞지 않아서 발생한 오류였다. 참고

    husky 실행 명령을 .git이 있는 root 디렉토리로 이동 후 실행하니 정상적으로 실행됐다

    {
      "script": {
        "prepare": "cd ../.. && husky"
      }
    }