개요
이번 블로그 포스트에서는 PnpM
을 사용하여 모노레포를 만드는 방법에 대해서 알아보겠습니다.
블로그 시리즈
이 블로그는 시리즈로 제작되었습니다. 다음 링크를 통해 다른 블로그 포스트도 확인해 보시기 바랍니다.
- [프로젝트 관리] 리포지토리 전략
- [JavaScript] 모노레포(Monorepo)를 위한 도구들
- [Monoepo] NodeJS의 모듈 불러오기
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Yarn Workspaces의 Hoisting
- [Monoepo] Yarn Workspaces의 명령어
- [Monoepo] PnpM을 사용하여 모노레포 만들기
PnpM
PnpM은 NodeJS 패키지 매니저중 하나로, NPM
, Yarn
과 동일한 역할을 합니다. PnpM
은 빠른 설치 속도와 공간 절약을 강조하며 다양한 프로젝트에서 사용되고 있습니다.
PnpM 설치
다음 명령어를 사용하여 PnpM
이 설치되어 있는지 확인합니다.
pnpm -v
설치가 되어 있지 않다면 다음 명령어를 실행하여 PnpM
을 설치합니다.
npm install -g pnpm
예제
PnpM
을 설치하였다면, PnpM
을 사용하여 모노레포를 구성해 봅시다. 모노레포를 구성하기 위해 다음과 같은 폴더와 파일 구조를 만듭니다.
.
├── package.json
└── src
├── module-a
│ ├── index.js
│ └── package.json
└── module-b
├── index.js
└── package.json
module-a
의 package.json
은 다음과 같습니다.
// src/module-a/package.json
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
module-b
의 package.json
은 다음과 같습니다.
// src/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
그리고 module-b
의 index.js
는 다음과 같습니다.
// src/module-b/index.js
console.log('module-b');
마지막으로 module-a
의 index.js
는 다음과 같습니다.
// src/module-a/index.js
console.log('module-a');
require('module-b');
이렇게 파일을 구성한 후, 다음 명령어를 실행하여 모듈을 잘 불러오는지 확인합니다.
node src/module-a/index.js
그럼 다음과 같이 에러가 발생하는 것을 확인할 수 있습니다.
module-a
node:internal/modules/cjs/loader:1073
throw err;
^
Error: Cannot find module 'module-b'
Require stack:
- /Users/deku/temp/temp/src/module-a/index.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1070:15)
at Module._load (node:internal/modules/cjs/loader:923:27)
at Module.require (node:internal/modules/cjs/loader:1137:19)
at require (node:internal/modules/helpers:121:18)
at Object.<anonymous> (/Users/deku/temp/temp/src/module-a/index.js:3:1)
at Module._compile (node:internal/modules/cjs/loader:1255:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1309:10)
at Module.load (node:internal/modules/cjs/loader:1113:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/Users/deku/temp/temp/src/module-a/index.js' ]
}
pnpm-workspace.yaml
PnpM
을 사용하여 모노레포를 구성하기 위해서는 pnpm-workspace.yaml
파일이 필요합니다. 루트 폴더에 pnpm-workspace.yaml
파일을 만들고 다음과 같이 수정합니다.
packages:
- 'src/*'
의존성 설치
module-a
가 module-b
를 사용하기 때문에, module-a
의 package.json
파일에 module-b
를 의존성으로 추가해야 합니다. 의존성을 추가하기 위해 src/module-a/package.json
파일을 열고 다음과 같이 수정합니다.
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"module-b": "workspace:*"
}
}
파일을 수정하였다면, 루트 폴더에서 다음 명령어를 실행하여 의존성을 설치합니다.
pnpm install
그런 다음 폴더 구조를 확인해 보면 다음과 같이 module-a
폴더안 node_modules
에 module-b
의 Symlink
가 생성된 것을 확인할 수 있습니다.
.
├── node_modules
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
└── src
├── module-a
│ ├── index.js
│ ├── node_modules
│ │ └── module-b -> ../../module-b
│ └── package.json
└── module-b
├── index.js
└── package.json
Symlink
에 관한 자세한 내용은 다음 링크를 참고하시기 바랍니다.
확인
이제 PnpM
을 사용하여 모노레포를 사용할 준비가 끝났습니다. 다음 명령어를 실행하여 모듈을 잘 불러오는지 확인합니다.
pnpm module-a start
그럼 다음과 같이 실행이 잘 되는 것을 확인할 수 있습니다.
module-a
module-b
module-a
의 node_modules
에 module-b
의 Symlink
가 생성되었기 때문에, 다음 명령어를 사용할 수 있습니다.
node ./src/module-a
module-b
는 의존성이 없으므로, 다음 명령어를 실행하면 문제없이 실행 되는 것을 확인할 수 있습니다.
pnpm module-b start
# module-b
node ./src/module-b
# module-b
완료
이것으로 PnpM
을 사용하여 모노레포를 구성하는 방법에 대해서 알아보았습니다. 여러분이 만약 Yarn
을 사용하지 않고 PnpM
을 사용하고 계신다면, 이 블로그 포스트를 참고하여 PnpM
으로 모노레포를 구성해 보시기 바랍니다.
제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!
앱 홍보
Deku
가 개발한 앱을 한번 사용해보세요.Deku
가 개발한 앱은 Flutter로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.