본문 바로가기
JavaScript

npm 라이브러리 만들고 사용하기

by curious week 2025. 6. 13.

 

목표

  • CLI로 실행: memo "메모 내용"
  • 실행 시, 현재 날짜 기준으로 memos/YYYY-MM-DD.txt 파일에 메모를 추가
  • TypeScript로 작성
  • bin 설정 포함해서 CLI 명령어처럼 실행 가능

프로젝트 구조

memo-cli/
├── package.json
├── tsconfig.json
├── src/
│   └── cli.ts
└── memos/
    └── (자동 생성됨)

1. package.json

{
  "name": "memo-cli-test",
  "version": "1.0.0",
  "type": "module",
  "bin": {
    "memo": "./src/cli.ts"
  },
  "scripts": {
    "dev": "bun src/cli.ts"
  },
  "dependencies": {},
  "devDependencies": {}
}

bin 항목 덕분에 memo 명령어로 CLI 실행 가능
bun 또는 tsx 환경에서 실행 가능


2. tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true
  },
  "include": ["src"]
}

3. src/cli.ts

#!/usr/bin/env bun

import { writeFileSync, appendFileSync, mkdirSync, existsSync } from 'fs';
import { join } from 'path';

// 메모 내용은 커맨드라인 인자로 입력받음
const memo = process.argv.slice(2).join(' ').trim();

if (!memo) {
  console.error('❌ 메모 내용을 입력해주세요.');
  process.exit(1);
}

// 오늘 날짜를 파일 이름으로 사용 (예: 2025-06-12.txt)
const now = new Date();
const dateStr = now.toISOString().split('T')[0];
const memoDir = 'memos';
const filePath = join(memoDir, `${dateStr}.txt`);

if (!existsSync(memoDir)) {
  mkdirSync(memoDir);
}

// 메모를 파일에 추가
const time = now.toTimeString().split(' ')[0];
const entry = `[${time}] ${memo}\n`;

appendFileSync(filePath, entry, { encoding: 'utf-8' });

console.log(`✅ 메모가 저장되었습니다: ${filePath}`);

bun 대신 tsx를 쓸 거면 shebang을 #!/usr/bin/env tsx로 바꿔야함


사용법

1. 설치 및 실행 권한

bun install
chmod +x src/cli.ts

2. CLI처럼 실행하려면

bun link     # 또는 npm link
memo "오늘도 열심히 공부했다!"

3. 결과

memos/2025-06-12.txt

[22:41:15] 오늘도 열심히 공부했다!

Unix 기반 셸(Bash, Zsh 등)에서 !!는 "직전 명령어 전체"를 재실행하는 히스토리 기능

"오늘도 열심히 공부했다!!" => '오늘도 열심히 공부했다bun link' 출력된다.


지금까지 구조 점검

.
├── node_modules        ✅ 의존성 설치됨
├── package.json        ✅ 기본 설정 됨 (bin 설정만 확인 필요)
├── src/
│   └── cli.ts          ✅ CLI 파일 존재
└── tsconfig.json       ✅ 타입스크립트 설정

여기까지 잘 진행했으니까, 이제 아래 순서만 마무리하면 바로 npm에 배포 가능


최종 배포 준비 체크리스트

1. cli.ts에 shebang 추가

shebang (#!) 이란?

shebang은 스크립트 파일을 실행할 때 어떤 인터프리터로 실행할지를 지정하는 특별한 주석 줄.
#!로 시작하기 때문에 shebang이라고 부르고, 유닉스/리눅스/맥OS에서 동작.

#!/usr/bin/env bun

bun으로 실행한다면 위처럼, tsx를 쓴다면 #!/usr/bin/env tsx로 변경

그리고 컴파일된 결과도 #!/usr/bin/env node 형태로 바꿔야 CLI에서 동작. 그대로 bun 사용하면 bun으로만 가능


2. package.json의 핵심 필드 확인

{
  "name": "memo-cli-test",      ← 유니크한 이름, 스코프 있으면 더 안전
  "version": "1.0.0",
  "type": "module",                  ← ESM 지원
  "main": "dist/cli.js",             ← 빌드 후 실행 파일 경로
  "bin": {
    "memo": "dist/cli.js"           ← CLI 명령어 등록
  },
  "scripts": {
    "build": "tsc"
  },
  "files": ["dist"],                ← 배포 대상 폴더 (src는 제외)
  "keywords": ["memo", "cli", "tool"], ← npm 사이트에 keyword로 올라감
  "author": "curiousweek",
  "license": "MIT"
}

memo 명령어가 등록되고, npm install -g 하면 전역 CLI로 작동함


3. CLI 코드 컴파일

bun x tsc

이렇게 하면 dist/cli.js 가 생성. 없으면 tsconfig.json에 outDir: "dist" 확인.

// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "declaration": true,
    "outDir": "dist"       // 반드시 이걸 넣어야 dist/ 폴더에 출력됨
  },
  "include": ["src"]
}

4. .npmignore 또는 "files" 필드로 배포 범위 지정

방법 1. .npmignore

src/
tsconfig.json
*.log

방법 2. "files" 필드 (package.json에 있음)

"files": ["dist"]

5. README.md 작성 (npm 페이지에서 보여짐)

간단히라도 아래 구조로 작성:

# memo-cli

Simple CLI tool to save daily memos.

## Installation

```bash
npm install -g memo-cli-test

npm install -g @yourname/memo-cli-test: @yourname/이런 건 org가 있을 때 사용

Usage

memo "Fighting!!"

npm 계정 생성 후

npm login

7. 배포하기

npm publish --access public

완료 후 테스트

다른 터미널에서 전역 설치해서 확인:

npm install -g memo-cli-test
memo "오늘도 열심히 살아간다"

 

 

 

'JavaScript' 카테고리의 다른 글

email.js로 backend 없이 메시지 전달 받기  (0) 2025.09.09
Node.js 입력/출력 정리  (3) 2025.08.24
JavaScript의 Object 객체와 주요 메서드  (1) 2025.03.21
정규표현식  (5) 2025.03.05
Bun  (1) 2025.02.11