모노레포 도구를 yarn berry로 선택한 배경과 기초 셋팅에 대해 다뤄보겠습니다.
현재 회사에서는 yarn 1.x
버전의 패키지 매니저를 사용하고있습니다.
다른 모노레포 도구가 있지만 yarn 1.x
을 사용하고 있는 상황이라면 점진적으로 3.x(berry)
로 마이그레이션하는게 바람직하다고 생각이 들었습니다.
npm
, yarn 1.x
와 달리 yarn berry
는 typeScript
로 작성되어 완전히 타입 체크가 되어 있다.
Plug'n'Play(Zero Install)
기존의 로컬 node_module
폴더 대신 패키지를 캐시 폴더에 저장하고, .pnp.cjs
파일에 의존성을 찾을 수 있는 정보가 기록된다. .pnp.cjs
를 이용하면 디스크 I/O없이 어떤 패키지가 어떤 라이브러리에 의존하는지, 각 라이브러리는 어디에 위치하는지를 바로 알 수 있다.
Zip File System
yarn pnp 시스템에서 각 의존성을 zip 아카이브로 관리된다.
따라서 기존 node_module
은 디렉토리 구조를 생성할 필요가 없어 설치가 빠른 속도로 완료된다.
Zero Install 덕분에 새로 저장소를 복제하거나 브랜치를 복사하더라도 yarn install
을 생략 할 수 있고, CI
에서 의존성 설치하는 부분에서 시간을 크게 단축할 수 있다.
$ yarn set version berry
$ yarn init
$ yarn add -D typescript @types/node
├── apps
│ ├── app 대시보드 서비스
│ ├── pay 결제모듈 서비스
│ └── backoffice 관리자 서비스
└── shared
├── ui 공유 컴포넌트
└── utils 유틸 함수, 타입 등
{
"name": "monorepo-test",
"packageManager": "yarn@4.0.2",
"workspaces": {
"packages": [
"apps/*",
"shared/*"
]
},
"devDependencies": {
...
}
...
}
위 프로젝트 구조에 따라루트 경로의 apps, shared 폴더 내부의
모든 폴더가 workspace에 속하도록 작성
packages 배열에 추가
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
...
},
"references": [
{
"path": "apps/pay"
},
{
"path": "apps/app"
},
{
"path": "apps/backoffice"
},
{
"path": "shared/ui"
},
{
"path": "shared/utils"
}
],
"include": [],
"exclude": ["apps/**/dist/**"]
}
각 tsconfig
의 경우 references
를 추가해준다.
각 프로젝트의 tsconfig
에 루트의 설정을 오버라이드할 수 있다.
prettier 설치
$ yarn add -D prettier
eslint와 충돌을 막아주는 config, plugin 설치
$ yarn add -D eslint-config-prettier eslint-plugin-prettier
prettier는 root에 하나의 파일로 정의
(속성 파일 내용은 생략)
root에 하나만 설정해도 되고 각각의 프로젝트에서 설정가능
eslint 설치
$ yarn add -D eslint
eslint init
$ npx eslint --init
추가 설치 설치
$ yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parse
(속성 파일 내용은 생략)
각 레파지토리 설정한 name
으로 접근이 가능하다.
{
"name": "@common/ui",
"packageManager": "yarn@4.0.2",
"main": "src/index.ts",
...
}
{
"name": "app",
"dependencies": {
"@common/ui": "workspace:*",
...
},
}
위와 같이 APP 워크스페이스 에서 UI를 import
할 수 있다.
{
"name": "monorepo-test",
"packageManager": "yarn@4.0.2",
"scripts": {
"app": "yarn workspace app",
"pay": "yarn workspace pay",
"common-ui": "yarn workspace @common/ui",
"common-utils": "yarn workspace @common/utils",
...
},
...
}
다음 게시글은 모노레포 예제 작성중 만난 이슈에 대해 다뤄보겠습니다.