
목표
- 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 |