예전에도 몇번 다루었던 모노레포를 제대로 구성해보지도 못했어서, 이번에는 앞으로 만들 모든 사이드프로젝트를 하나의 모노레포로 관리해보기 위해서 모노레포를 구성해보고자 한다.
익숙한 yarn 대신 pnpm을 사용해서 구성해보자.
1. pnpm 설치
pnpm을 설치하는 방법은 여러가지가 있는데 그 중 brew와 npm을 통한 설치 방법 둘 중 고민했다.
- npm을 통한 설치: Node.js와 긴밀히 연동되며, 주로 Node.js 프로젝트와 작업할 때 편리한 방식이다. 하지만 Node.js 버전을 여러 개 관리할 때는 불편할 수 있다.
- Homebrew를 통한 설치: Node.js 버전과 무관하게 시스템 전역에서 pnpm을 사용할 수 있으며, macOS 시스템과 통합된 패키지 관리가 가능하다. 여러 버전의 Node.js와 함께 사용해야 하는 경우 더 유리할 수 있다.
pnpm을 npm에 독립적으로 사용할 것이냐, 의존적으로 사용할 것이냐의 차이인데... 멀리 보면 brew가 좋을것 같지만, 당분간은 node 환경의 프로젝트만 진행하지 않을까싶고, brew를 사용했을때 다른 이슈들이 많이 발생하지 않을까 싶어서, npm을 사용할 것이다.
$ npm install -g pnpm
2. 프로젝트 구성
pnpm 프로젝트 초기화
$ mkdir projects
$ cd projects
$ pnpm init
2-1. 프로젝트 구조
프로젝트 구조는 크게 재사용 가능한 패키지나 라이브러리, 여러 프로젝트 형태로 나누자.
my-monorepo/
├── packages/ # 재사용 가능한 패키지나 라이브러리
│ ├── ui-lib/ # 공통 컴포넌트 라이브러리 (예: 디자인 시스템)
│ └── utils/ # 공통 유틸리티 함수
├── apps/ # 실제 프론트엔드 애플리케이션들이 위치
│ ├── app1/ # 예: React or Next.js 앱
│ └── app2/ # 또 다른 앱
├── node_modules/ # pnpm이 사용하는 전역 노드 모듈 폴더 (Hoisting)
├── package.json # 루트 패키지 매니저 설정
└── pnpm-workspace.yaml # 워크스페이스 설정 파일
2.2. 의존성 설정
root에 의존성을 설치하게 되면, 하위 프로젝트에서 의존성을 설치하지 않아도 해당 의존성을 사용할 수 있다.
이를 위해 pnpm-workspace.yaml을 통해 모노레포에서 어떤 디렉토리를 워크스페이스로 인식할지를 정의할 수 있다.
pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
그 다음 root package.json에서 공통적으로 사용되는 스크립트나 의존성을 정의하자.
우선은 공통으로 사용될 의존성은 typescript, eslint, prettier 정도일것같다.
typescript 설치
$ pnpm add -D typescript
$ pnpm tsc --init
eslint 설치
$ pnpm add -D eslint
$ pnpm eslint --init
prettier 설치
pnpm add -D prettier
echo {} > .prettierrc
eslint, prettier 통합
$ pnpm add -D eslint-config-prettier eslint-plugin-prettier
.eslintrc.json에서 prettier 관련 설정
{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"plugins": ["@typescript-eslint", "prettier"],
"rules": {
"prettier/prettier": "error"
}
}
각각의 세부 설정은 본인의 스타일에 맞게 설정하면 될 것 같다.
script 설정
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc"
}
스크립트 역시 필요한 스크립트를 스타일에 맞게 설정하면 될 것 같다.