Javascript

[JS] Turborepo를 활용한 공통 라이브러리 관리

kyoulho 2024. 8. 31. 17:25

Turborepo를 활용하면 모노레포 환경에서 공통 라이브러리와 설정을 효과적으로 관리할 수 있다. 병렬 빌드, 캐싱, 전역 스크립트 등의 기능을 통해 개발 프로세스를 최적화하고, 공통 패키지를 통해 코드의 일관성과 품질을 유지할 수 있다.

  • 병렬 빌드: 여러 작업을 동시에 실행하여 빌드 속도를 향상시킨다.
  • 캐싱: 이전 작업의 결과를 재사용하여 빌드 및 테스트 시간을 단축시킨다.
  • 워크스페이스 관리: 여러 패키지를 효율적으로 관리하며, 종속성을 명확히 한다.
  • 전역 스크립트: 모노레포 내 모든 프로젝트에 대해 통합된 스크립트를 실행할 수 있다.

구조

Turborepo의 일반적인 디렉토리 구조는 다음과 같다:

my-turborepo/
│
├── apps/
│   ├── web/
│   └── mobile/
│
├── packages/
│   ├── ui/
│   ├── utils/
│   └── eslint-config/
│
├── .eslintrc.js
├── tsconfig.json
├── package.json
└── turbo.json

 

최상위 package.json

모노레포의 최상위 package.json 파일은 모든 프로젝트와 라이브러리에 대한 전역 의존성과 스크립트를 정의하는 중요한 역할을 한다. 이 파일의 scripts 필드는 모노레포 전체에서 사용할 수 있는 명령어들을 설정하며, 이 명령어들은 모노레포 내 모든 프로젝트에서 일관되게 실행된다.
 
특히, scripts 필드에 정의된 명령어들은 모노레포 전체에 걸쳐 공통적으로 사용되며, 각 프로젝트의 package.json에서 정의된 같은 이름의 명령어를 덮어쓰지 않는다. 대신, 모노레포의 최상위에서 설정된 스크립트는 프로젝트와 라이브러리의 빌드, 개발, 테스트, 린트 등 전반적인 작업을 통합적으로 관리하고 실행할 수 있게 한다.

{
  "name": "my-turborepo",
  "version": "1.0.0",
  "private": true,
  "devDependencies": {
    "turbo": "latest",
    "prettier": "^3.1.1"
  },
  "scripts": {
    "build": "turbo build",
    "dev": "turbo dev",
    "test": "turbo test",
    "lint": "turbo lint"
  }
}

 

turbo.json

Turborepo의 구성 파일로, 병렬화 및 캐싱과 같은 기능을 설정할 수 있다. 이 파일에서는 각 작업의 의존성과 출력 파일을 정의할 수 있다. build 작업은 모든 패키지의 build 작업에 의존하고, 결과물을 dist/** 디렉토리에 저장한다.

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": []
    },
    "lint": {
      "dependsOn": ["^lint"],
      "outputs": []
    }
  }
}

 

공통 라이브러리 및 설정 관리

공통 라이브러리 패키지 생성

packages 디렉토리 내에 공통 라이브러리를 생성하여 여러 프로젝트에서 재사용할 수 있다. 예를 들어, uiutils 패키지를 생성할 수 있다. 이 ui 패키지는 여러 애플리케이션에서 공통으로 사용할 수 있는 UI 컴포넌트를 제공한다.

예시: packages/ui/package.json

{
  "name": "@my-org/ui",
  "version": "1.0.0",
  "main": "index.js",
  "devDependencies": {
    "react": "^18.0.0"
  }
}

공통 ESLint 설정 패키지

ESLint와 같은 설정 패키지는 여러 프로젝트에서 일관된 규칙을 적용하는 데 유용하다. packages/eslint-config 디렉토리 내에 공통 ESLint 설정을 정의할 수 있다.

예시: packages/eslint-config/package.json

{
  "name": "@my-org/eslint-config",
  "version": "1.0.0",
  "main": "index.js",
  "devDependencies": {
    "eslint": "^8.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "@typescript-eslint/eslint-plugin": "^5.0.0"
  }
}

예시: packages/eslint-config/index.js

module.exports = {
  extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: "module",
  },
  rules: {
    // 커스터마이징할 규칙들
  },
};

 

프로젝트별 설정 적용

각 프로젝트는 공통 설정 패키지를 의존성으로 추가하고, ESLint 설정 파일에서 이 공통 설정을 extends하여 사용할 수 있다.

예시: apps/web/package.json

{
  "name": "web",
  "dependencies": {
    "@my-org/eslint-config": "*"
  }
}

예시: apps/web/.eslintrc.js

module.exports = {
  root: true,
  extends: ["@my-org/eslint-config"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: "./tsconfig.json",
  },
};

전역 설정

모노레포의 최상위 .eslintrc.js 파일에서도 공통 설정을 extends하여 사용할 수 있다. 이를 통해 모노레포 전체에서 공통의 ESLint 규칙을 적용할 수 있다.

예시: 최상위 .eslintrc.js

module.exports = {
  ignorePatterns: ["apps/**", "packages/**"],
  extends: ["@my-org/eslint-config"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: true,
  },
};

 

728x90

'Javascript' 카테고리의 다른 글

[JS] ESLint와 TypeScript 설정에서 ES 버전 차이  (0) 2024.09.01
[JS] Express 기초  (0) 2024.08.02
[JS] 타입스크립트의 Record 타입  (0) 2024.07.31
[JS] peerDepedencies  (0) 2024.07.30
순수 함수  (3) 2024.07.22