개요
이번 블로그 포스트에서는 모노레포를 이해하기 위한 기본 지식으로 NodeJS
가 모듈을 불러오는 방법에 대해서 알아보도록 하겠습니다.
블로그 시리즈
이 블로그는 시리즈로 제작되었습니다. 다음 링크를 통해 다른 블로그 포스트도 확인해 보시기 바랍니다.
- [프로젝트 관리] 리포지토리 전략
- [JavaScript] 모노레포(Monorepo)를 위한 도구들
- [Monoepo] NodeJS의 모듈 불러오기
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Yarn Workspaces의 Hoisting
- [Monoepo] Yarn Workspaces의 명령어
- [Monoepo] pnpm을 사용하여 모노레포 만들기
모듈
자바스크립트에서 모듈은 코드를 구성하고 재사용 가능한 단위로 분리하는 데 사용되는 기능입니다. 모듈을 사용하면 코드를 더 쉽게 유지보수하고 확장할 수 있습니다. ECMAScript 2015(ES6)부터 자바스크립트에 원래 없었던 모듈 시스템이 도입되었습니다.
모듈은 파일 수준에서 코드를 캡슐화하고, 필요한 기능을 다른 파일에서 가져와 사용할 수 있도록 해줍니다. 모듈을 사용하면 전역 스코프의 충돌을 방지하고, 코드의 의존성을 명확하게 관리할 수 있습니다.
JavaScript에서 모듈을 사용하기 위해 다음과 같은 키워드를 사용합니다.
import
: 다른 모듈에서 내보낸 기능을 현재 모듈에서 가져옵니다.export
: 현재 모듈에서 외부로 내보낼 함수, 변수, 클래스 등을 지정합니다.
JavaScript에서 다음과 같이 모듈을 만들 수 있습니다.
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
이렇게 만든 모듈은 다음과 같이 사용이 가능합니다.
// main.js
import { add, subtract } from './math';
console.log(add(5, 3)); // 8
console.log(subtract(7, 2)); // 5
모듈 불러오기
JavaScript에서 모듈을 불러오는 방법은 크게 두 가지가 있습니다.
File path
를 이용하는 방법Package name
을 이용하는 방법
File path
File path
를 이용하여 모듈을 추가할 때는 다음과 같이 상대 경로(Relative path)와 절대 경로(Absolute path)를 사용할 수 있습니다.
// Relative path
import { add, subtract } from '../some/file/path/math';
// Absolute path
import { add, subtract } from '/src/math';
Package name
node_modules
폴더 하위에 있는 모듈은 Package name
을 이용하여 불러올 수 있습니다.
// react module exists in node_modules
import React from 'react';
모듈 불러오기 우선순위
NodeJS
에서 모듈을 불러올 때, 우선 동일한 폴더에서 해당 모듈이 있는지, 동일한 폴더의 node_modules
에 모듈이 확인합니다. 만약, 동일한 폴더에 존재하지 않는다면, 부모 폴더의 node_modules
폴더를 찾게 되고, 부모 폴더의 node_modules
에도 존재하지 않는 경우, 부모 폴더의 상위 폴더의 node_modules
에서 모듈을 찾게 됩니다.
예제
NodeJS
가 모듈을 불러오는 방법을 확인하기 위해 다음과 같은 폴더 구조를 만들어 보겠습니다.
.
└── 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' ]
}
이제 src
폴더명을 node_modules
로 변경하고 다시 실행해 봅니다.
node node_modules/module-a/index.js
그럼 다음과 같이 문제없이 실행되는 것을 확인할 수 있습니다.
module-a
module-b
폴더명이 src
인 경우, module-a
에서 require('module-b');
을 통해 module-b
를 불러올 때, 파일 경로가 아니므로 동일한 폴더의 node_modules
에서 module-b
를 찾게 됩니다. node_modules
가 현재 폴더에 존재하지 않으므로, 부모 폴더의 node_modules
를 확인합니다. 부모 폴더에도 node_modules
가 없기 때문에 MODULE_NOT_FOUND
에러가 발생하는 것을 확인할 수 있습니다.
폴더명을 node_modules
로 변경한 후, 동일한 코드를 실행하면, module-a
폴더에 node_modules
가 존재하지 않기 때문에, 부모 폴더에서 node_modules
를 찾게 됩니다. 부모 폴더에는 우리가 이름을 변경한 node_modules
가 존재하고, 해당 폴더의 module-b
가 존재하기 때문에 문제가 발생하지 않고 잘 실행되는 것을 확인할 수 있습니다.
완료
이것으로 NodeJS
가 모듈을 불러오는 방법에 대해서 알아보았습니다. NodeJS
가 모듈을 불러오는 방법은 모노레포로 프로젝트를 구성하는데 도움이 되는 지식이므로 이번 블로그 포스트에서 소개해 보았습니다. 여러분도 이번 기회에 NodeJS
가 모듈을 불러오는 방법에 대해서 다시 한번 이해해 보시기 바랍니다.
제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!
앱 홍보
Deku
가 개발한 앱을 한번 사용해보세요.Deku
가 개발한 앱은 Flutter로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.