개요
모노레포에서 여러 모듈들의 의존성을 연결할 때, Symlink
를 활용하게 됩니다. 이번 블로그 포스트에서는 모노레포를 이해하기 위한 기본 지식인 Symlink(Symbolic Link)
에 대해서 알아보도록 하겠습니다.
블로그 시리즈
이 블로그는 시리즈로 제작되었습니다. 다음 링크를 통해 다른 블로그 포스트도 확인해 보시기 바랍니다.
- [프로젝트 관리] 리포지토리 전략
- [JavaScript] 모노레포(Monorepo)를 위한 도구들
- [Monoepo] NodeJS의 모듈 불러오기
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Yarn Workspaces의 Hoisting
- [Monoepo] Yarn Workspaces의 명령어
- [Monoepo] pnpm을 사용하여 모노레포 만들기
Symlink
Symlink
는 Symbolic Link
의 줄임말로, 파일
또는 디렉토리
에 대한 바로가기(System shortcut)
라고 생각하시면 됩니다.
Symlink는 주요 OS(macOS, Windows, Linux)에서 지원하는 기본 기능입니다. 또한 NodeJS
의 패키지 매니저인 npm
과 yarn
에서도 지원하고 있습니다.
예제
npm
과 yarn
이 제공하는 Symlink
기능을 확인하기 위한 예제를 만들어 봅시다. 우선, 다음과 같이 폴더와 파일 구조를 생성합니다.
.
└── 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' ]
}
Symlink 생성
Symlink
기능을 확인하기 위해 module-b
폴더로 이동합니다.
cd src/module-b
이동한 후, 다음 명령어를 실행하여 Symlink
를 사용할 준비를 합니다.
npm link
# yarn link
이후, module-b
를 사용하는 module-a
폴더로 이동합니다.
cd ..
cd module-a
module-a
폴더로 이동하였다면, 다음 명령어를 사용하여 module-b
에 대한 Symlink
를 생성합니다.
npm link module-b
이렇게 link
명령어를 실행하면 다음과 같이 module-a
폴더의 node_modules
폴더가 생성되고 modules-b
의 Symlink
가 생성된 것을 확인할 수 있습니다.
.
├── index.js
├── node_modules
│ └── module-b -> ../../module-b
└── package.json
이 Symlink
폴더는 module-b
를 복사한 것이 아니라 module-b
자체와 연동이 되어 있습니다. 따라서 src/module-b/index.js
파일을 수정하면 src/module-a/node_modules/module-b/index.js
파일도 같이 수정이 되며, 반대로 src/module-a/node_modules/module-b/index.js
파일을 수정하면 src/module-b/index.js
파일도 같이 수정이 됩니다.
Symlink 확인
이제 프로젝트의 루트 폴더(/
)로 이동한 후, 다음 명령어를 실행하여 모듈을 잘 불러오는지 확인합니다.
# cd ../..
node src/module-a/index.js
그럼 다음과 같이 문제없이 잘 실행되는 것을 확인할 수 있습니다.
module-a
module-b
이제 src/module-b/index.js
파일 내용을 다음과 같이 수정합니다.
console.log('module-b!!!!');
수정후, src/module-a/node_modules/module-b/index.js
파일을 열어보면 위에서 수정한 내용이 반영되어 있는 것을 확인할 수 있습니다. 물론, 다음 명령어를 실행하면, 변경된 내용이 잘 출력되는 것을 확인할 수 있습니다.
node src/module-a/index.js
module-a
module-b!!!!
완료
이것으로 모노레포를 사용하기 위한 기초 지식인 Symlink
에 대해서 알아보았습니다. 모노레포에서 여러 모듈들의 의존성을 연결할 때, Symlink
를 활용하므로 이번 블로그 포스트를 통해 Symlink
를 이해해 두면 모노레포를 사용하는데 도움이 될 것입니다.
제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!
앱 홍보
Deku
가 개발한 앱을 한번 사용해보세요.Deku
가 개발한 앱은 Flutter로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.