Package, npm, module

1. 패키지와 모듈 시스템

Node.js는 확장성 있는 네트워크 애플리케이션을 구축하기 위한 JavaScript 런타임 환경이다.

Node.js의 강점 중 하나는 넓은 패키지 생태계로, 수많은 라이브러리를 쉽게 활용할 수 있다.

 

1.1. 패키지와 모듈의 차이점

패키지(Package)란 package.json 파일과 이 파일에 정의된 파일 또는 디렉터리의 집합이다.

패키지는 재사용 가능한 코드의 단위로, 다른 프로젝트에서 사용할 수 있도록 설계되었다.

모듈(Module)은 node_modules 디렉터리 아래에 있는 파일 또는 디렉터리로, require() 또는 import 구문을 통해 로드할 수 있는 코드 단위이다.

 

모든 패키지는 모듈이 될 수 있지만, 모든 모듈이 패키지인 것은 아니다.

패키지 ⊂ 모듈

 

1.2. Node.js의 모듈 시스템

Node.js는 CommonJS 모듈 시스템을 기반으로 하며, ES 모듈 시스템도 지원한다.

 

1) CommonJS 방식:

// math.js (모듈 정의)
function add(a, b) {
  return a + b;
}

module.exports = { add };

// app.js (모듈 사용)
const math = require('./math');
console.log(math.add(2, 3)); // 5

 

2) ES 모듈 방식:

// math.js (모듈 정의)
export function add(a, b) {
  return a + b;
}

// app.js (모듈 사용)
import { add } from './math';
console.log(add(2, 3)); // 5

 

ES 모듈을 사용하려면 package.json에 "type": "module" 필드를 추가하거나 파일 확장자를 .mjs로 지정해야 한다.

 

 

2. NPM(Node Package Manager)

2.1. NPM이란?

NPM은 자바스크립트 프로그래밍 언어를 위한 패키지 관리자이다.

Node.js 설치 시 함께 제공되며, 자바스크립트 패키지를 설치, 공유, 배포하는 데 사용된다.

 

1) 웹사이트(npmjs.com): 패키지 검색 및 정보 제공
2) CLI(Command Line Interface): 터미널에서 패키지 관리
3) 레지스트리: 패키지 메타데이터와 배포 파일 저장소

 

2.2. 주요 NPM 명령어

1) 패키지 초기화:

npm init

 

2) 패키지 설치:

npm install [패키지명]        # 로컬 설치
npm install -g [패키지명]     # 전역 설치
npm install [패키지명] --save-dev  # 개발 의존성으로 설치

 

3) 패키지 제거:

npm uninstall [패키지명]

 

4) 패키지 업데이트:

npm update [패키지명]

 

5) 스크립트 실행:

npm run [스크립트명]

 

2.3. package.json

package.json은 Node.js 프로젝트의 메타데이터를 담고 있는 파일이다.

프로젝트 구성, 의존성, 스크립트 등 다양한 정보를 JSON 형식으로 정의한다.

 

ex)

{
  "name": "my-project",        // 프로젝트 이름
  "version": "1.0.0",          // 버전 (semver 형식)
  "description": "",           // 프로젝트 설명
  "main": "index.js",          // 진입점 파일
  "scripts": {                 // 실행 스크립트
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },
  "dependencies": {            // 프로덕션 의존성
    "express": "^4.18.2"
  },
  "devDependencies": {         // 개발 의존성
    "nodemon": "^2.0.22"
  },
  "keywords": [],              // 검색 키워드
  "author": "",                // 작성자
  "license": "ISC"             // 라이선스
}

 

 

3. 패키지 잠금과 의존성 관리

3.1. package-lock.json

package-lock.json은 설치된 패키지의 정확한 버전과 의존성 트리를 기록하는 파일이다.

 

목적:

1) 정확한 의존성 트리 유지
2) 일관된 설치 보장
3) 종속성 충돌 예방

 

npm install 명령을 실행하면 자동으로 생성 또는 업데이트된다.

 

ex)

{
  "name": "my-project",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "my-project",
      "version": "1.0.0",
      "dependencies": {
        "express": "^4.18.2"
      }
    },
    "node_modules/express": {
      "version": "4.18.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
      "integrity": "sha512-3OHGXZ...",
      "dependencies": {
        "accepts": "~1.3.8",
        "body-parser": "1.20.1",
        // ... 더 많은 의존성
      }
    }
    // ... 전체 의존성 트리
  }
}

 

3.2. 의존성 버전 관리

NPM은 Semantic Versioning(SemVer)을 사용하여 패키지 버전을 관리한다.

SemVer는 주(Major).부(Minor).수(Patch) 형식으로 구성된다.

  • 주 버전: 호환되지 않는 API 변경
  • 부 버전: 하위 호환되는 기능 추가
  • 수 버전: 하위 호환되는 버그 수정

버전 범위 지정 기호:

  • ^: 호환되는 최신 버전(주 버전 고정)
    • 예: ^1.2.3 → 1.x.x (1.2.3 이상, 2.0.0 미만)
  • ~: 근사한 버전(주.부 버전 고정)
    • 예: ~1.2.3 → 1.2.x (1.2.3 이상, 1.3.0 미만)
  • >, >=, <, <=: 특정 버전 이상/이하
  • * 또는 x: 모든 버전
  • 1.2.3 - 2.3.4: 범위 지정

다만, 이 버전을 엄격하게 지키지 않는 패키지도 있다는 것을 유의해야한다.

 

3.3. peerDependencies

peerDependencies는 해당 패키지가 호스트 패키지의 특정 의존성에 의존하는 것을 명시한다.

주로 플러그인이나 확장 모듈에서 사용되며, 호환성을 보장하기 위해 필요하다.

 

{
  "name": "my-plugin",
  "version": "1.0.0",
  "peerDependencies": {
    "react": "^18.0.0"
  }
}

 

 

4. 간이 패키지 만들기

개인적으로 간단한 패키지를 만들어 보는 것이 전체적인 구조를 이해하는데에 도움이 됐다.

여기서는 덧셈 기능만 있는 간단한 패키지를 만들어 보겠다.

 

4.1. 프로젝트 초기화

먼저 새 디렉터리를 만들고 프로젝트를 초기화한다

mkdir sample-package
cd sample-package
npm init -y

 

4.2. 패키지 구조 설계

sample-package/
├── index.js         # 메인 진입점
├── src/             # 소스 코드
│   └── operations.js
├── README.md        # 문서
├── package.json     # 패키지 메타데이터
└── .gitignore       # Git 무시 파일

 

4.3. 구현

src/operations.js:

/**
 * 두 수의 합을 반환한다.
 * @param {number} a 첫 번째 숫자
 * @param {number} b 두 번째 숫자
 * @returns {number} 두 수의 합
 */
function add(a, b) {
  return a + b;
}
module.exports = {
  add,
};

 

index.js:

const operations = require('./src/operations');

// 직접 내보내기
module.exports = operations;

// 또는 다음과 같이 개별적으로 내보낼 수도 있음:
// module.exports = {
//   add: operations.add,
// };

 

package.json:

{
  "name": "sample-package",
  "version": "1.0.0",
  "description": "간단한 패키지",
  "main": "index.js",
  "scripts": {
    "test": "node test/test.js"
  },
  "keywords": ["math", "calculator", "operations"],
  "author": "Mumu",
  "license": "MIT"
}

 

4.4. 문서 작성

README.md:

# Sample Package

간단한 덧셈 연산을 제공하는 JavaScript 패키지입니다.

## 설치

```bash
npm install sample-package

 

사용 예시:

const sample = require('sample-package');

// 덧셈
console.log(sample.add(2, 3));  // 5

 

4.5. 로컬에서 패키지 사용

패키지를 로컬에서 테스트하기 위해 npm link를 사용할 수 있다.

# 패키지 디렉터리에서
npm link

# 다른 프로젝트에서
npm link sample-package

 

또는 로컬 경로를 직접 지정하여 설치할 수도 있다.

# 다른 프로젝트에서
npm install /path/to/sample-package

 

4.6. npm 레지스트리 배포

1) npm 계정 생성 및 로그인
2) npm adduser # 계정이 없는 경우 npm login # 이미 계정이 있는 경우
3) 배포
4) npm publish

 

비공개 패키지로 배포하려면 패키지 이름을 스코프로 지정한다.

{
  "name": "@username/sample-package",
  "version": "1.0.0",
  ...
}

 

'학습 > Node.js' 카테고리의 다른 글

Axios  (0) 2025.04.24
Express  (0) 2025.04.18
서버 연결  (0) 2025.04.17
node.js란?  (0) 2025.04.17