[Monorepo] NodeJS의 모듈 불러오기

2024-01-23 hit count image

JavaScript로 개발할 프로젝트에서 모노레포(Monorepo)를 사용하기 위한 지식으로 NodeJS가 모듈을 불러오는 방법에 대해서 알아보도록 하겠습니다.

개요

이번 블로그 포스트에서는 모노레포를 이해하기 위한 기본 지식으로 NodeJS가 모듈을 불러오는 방법에 대해서 알아보도록 하겠습니다.

블로그 시리즈

이 블로그는 시리즈로 제작되었습니다. 다음 링크를 통해 다른 블로그 포스트도 확인해 보시기 바랍니다.

모듈

자바스크립트에서 모듈은 코드를 구성하고 재사용 가능한 단위로 분리하는 데 사용되는 기능입니다. 모듈을 사용하면 코드를 더 쉽게 유지보수하고 확장할 수 있습니다. 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-apackage.json은 다음과 같습니다.

// src/module-a/package.json
{
  "name": "module-a",
  "version": "1.0.0",
  "main": "index.js"
}

module-bpackage.json은 다음과 같습니다.

// src/module-b/package.json
{
  "name": "module-b",
  "version": "1.0.0",
  "main": "index.js"
}

그리고 module-bindex.js는 다음과 같습니다.

// src/module-b/index.js
console.log('module-b');

마지막으로 module-aindex.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가 모듈을 불러오는 방법에 대해서 다시 한번 이해해 보시기 바랍니다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

블로그를 운영하면서 좋은 기회가 생겨 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
[심통]현장에서 바로 써먹는 리액트 with 타입스크립트 : 리액트와 스토리북으로 배우는 컴포넌트 주도 개발, 심통
Posts