개요
이번 블로그 포스트에서는 Yarn
의 Workspaces
를 사용하여 모노레포를 구성하는 방법에 대해서 알아보도록 하겠습니다.
블로그 시리즈
이 블로그는 시리즈로 제작되었습니다. 다음 링크를 통해 다른 블로그 포스트도 확인해 보시기 바랍니다.
- [프로젝트 관리] 리포지토리 전략
- [JavaScript] 모노레포(Monorepo)를 위한 도구들
- [Monoepo] NodeJS의 모듈 불러오기
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Yarn Workspaces의 Hoisting
- [Monoepo] Yarn Workspaces의 명령어
- [Monoepo] pnpm을 사용하여 모노레포 만들기
Yarn Workspaces
이전 블로그 포스트인 모노레포를 위한 도구
에서 자바스크립트 패키지 매니저인 Yarn
의 Workspaces
를 소개하였습니다.
이번 블로그 포스트에서는 실제로 Yarn
의 Workspaces
기능을 사용하여 모노레포를 구성하는 방법에 대해서 알아보도록 하겠습니다.
- 공식 문서: Workspaces
Yarn
의 Workspaces
는 이전 블로그 포스트에서 소개한 Symlink
를 통해 여러 프로젝트를 단일 코드베이스에서 관리할 수 있게 해주는 기능입니다. 이 기능을 사용하면 쉽게 모노레포를 구성할 수 있습니다.
예제
yarn
이 제공하는 Workspace
기능을 확인하기 위한 예제를 만들어 봅시다. 우선, 다음과 같이 폴더와 파일 구조를 생성합니다.
.
└── 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"
}
module-b
의 package.json
은 다음과 같습니다.
// src/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"main": "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' ]
}
Yarn Workspaces 설정
이제 Yarn
의 Workspaces
를 사용하여 module-a
에서 module-b
를 사용할 수 있게 만들어 보겠습니다. 우선 루트 폴더(/
)에서 다음 명령어를 사용하여 Yarn
의 Workspaces
를 사용할 준비를 합니다.
yarn init -y
그럼 루트 폴더에 다음과 같은 내용을 포함한 package.json
이 생성되는 것을 확인할 수 있습니다.
{
"name": "monorepo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
Yarn
의 Workspaces
를 사용하기 위해서는 이 package.json
파일을 다음과 같이 수정해야 합니다.
{
"name": "monorepo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"workspaces": {
"packages": ["src/module-a", "src/module-b"]
}
}
모노레포는 여러 프로젝트를 가지고 있는 단일 코드베이스이기 때문에 npm
레지스트리와 같은 곳에 배포할 필요가 없습니다. 따라서 private
을 true
로 설정하여 모노레포가 배포되지 않도록 합니다. Yarn V1
에서는 필수로 설정해야 하지만, Yarn V2
부터는 설정하지 않아도 됩니다. 안전하게 관리하기 위해 private
을 true
로 설정하는 것을 권장합니다. 물론, 모노레포안에 있는 개별 프로젝트는 배포할 수 있으므로 각각의 프로젝트는 private
을 설정하지 않아도 됩니다.
Workspaces
는 배열([]
)이나 오브젝트({}
)를 설정할 수 있습니다. Yarn
에서는 오브젝트 형식으로 작성하는 것을 권장하고 있습니다. Workspaces
안에 packages
라는 키로 배열을 만들고 각각의 모듈을 추가하였습니다. 이와 같이 각각 지정해도 되지만 다음과 같이 *
을 사용하여 간단하게 모든 모듈을 지정할 수도 있습니다.
{
"name": "monorepo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"workspaces": {
"packages": ["src/*"]
}
}
Yarn Workspaces 확인
이것으로 Yarn
의 Workspaces
를 사용할 준비가 끝났습니다. 이제 다음 명령어를 실행하여 패키지를 설치합니다.
yarn install
그럼 다음과 같이 루트 폴더에 node_modules
폴더가 생기가 Symlink
를 통해 각각의 모듈들이 연결된 것을 확인할 수 있습니다.
.
├── node_modules
│ ├── module-a -> ../src/module-a
│ └── module-b -> ../src/module-b
├── package.json
├── src
│ ├── module-a
│ │ ├── index.js
│ │ └── package.json
│ └── module-b
│ ├── index.js
│ └── package.json
└── yarn.lock
이제 다음 명령어를 실행하여 module-a
에서 module-b
를 사용할 수 있는지 확인해 보겠습니다.
node src/module-a/index.js
그럼 다음과 같이 문제없이 module-a
가 실행되는 것을 확인할 수 있습니다.
module-a
module-b
물론 Symlink
로 연결된 것이기 때문에 module-b
의 코드를 수정하면 module-a
에서도 수정된 코드를 사용할 수 있습니다. src/module-b/index.js
파일을 열고 다음과 같이 수정합니다.
console.log('module-b!!!');
그리고 다음 명령어를 실행하여 변경된 내용이 잘 표시되는 확인합니다.
node src/module-a/index.js
그럼 다음과 같이 변경된 내용이 잘 표시되는 것을 확인할 수 있습니다.
module-a
module-b!!!
.gitignore
Git
으로 소스코드를 관리하고 있다면, .gitignore
파일을 만들고 다음과 같이 수정하여 node_modules
폴더를 Git
에서 제외하도록 합니다.
# .gitignore
node_modules
완료
이것으로 모노레포를 사용하기 위해 Yarn
의 Workspaces
를 사용하는 방법에 대해서 알아보았습니다. Yarn
의 Workspaces
는 기본적으로 Symlink
로 동작하므로 Symlink
에 대해 이해하면 좋습니다. Symlink
에 대해 자세히 알고 싶다면 이전 블로그 포스트를 참고해 주시기 바랍니다.
이제 여러분도 Yarn
의 Workspaces
를 사용하여 모노레포를 구성해 보시기 바랍니다.
제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!
앱 홍보
Deku
가 개발한 앱을 한번 사용해보세요.Deku
가 개발한 앱은 Flutter로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.