본문 바로가기
개발 팁

npm 패키지 배포 전 체크리스트 — npm pack 활용법

by 루까(Luka) 2026. 2. 25.
반응형

npm에 패키지를 배포하고 나서 "아, 이걸 빠뜨렸네"를 겪고 나면 버전을 올려야 한다. 배포 전에 확인할 것들을 한 곳에 정리해둔다.


package.json 핵심 필드

배포에 직접 영향을 주는 필드들이다.

{
  "name": "@lukaplayground/my-package",
  "version": "1.0.0",
  "description": "한 줄 설명",
  "type": "module",
  "main": "src/index.js",
  "bin": {
    "my-cmd": "bin/my-cmd.js"
  },
  "files": [
    "bin/",
    "src/",
    "README.md",
    "LICENSE"
  ],
  "engines": {
    "node": ">=18.0.0"
  },
  "keywords": ["keyword1", "keyword2"],
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/username/my-package.git"
  }
}
필드 역할 주의사항
name 패키지 이름 scoped(@org/name)면 조직 계정 필요
version 배포 버전 한 번 배포한 버전은 덮어쓸 수 없음
type 모듈 시스템 "module" = ESM, 없으면 CommonJS
main 진입점 require() 또는 import 시 로드되는 파일
bin CLI 명령어 등록 npx 또는 글로벌 설치 시 사용
files 배포 포함 파일 명시 안 하면 .gitignore 제외 전체 포함
engines Node.js 최소 버전 ESM + top-level await는 Node 18 이상

files 필드 — 배포 크기의 핵심

files 배열을 명시하지 않으면 .gitignore에 없는 파일이 전부 들어간다. 테스트 파일, 설정 파일, .env.example까지 딸려간다.

"files": [
  "bin/",
  "src/",
  "README.md",
  "LICENSE"
]

files 설정과 무관하게 항상 포함되는 파일들이 있다.

  • package.json
  • README.md (대소문자 무관)
  • LICENSE (대소문자 무관)
  • main에 지정된 파일

반대로 설정과 무관하게 항상 제외되는 파일들도 있다.

  • .git/
  • node_modules/
  • .env 계열

npm pack — 배포 전 반드시 확인

실제 배포 전에 어떤 파일이 패키지에 들어가는지 확인하는 명령어다.

npm pack --dry-run

--dry-run은 실제 파일을 만들지 않고 목록만 출력한다.

npm notice Tarball Contents
npm notice 1.1kB  LICENSE
npm notice 2.3kB  README.md
npm notice 1.2kB  bin/commitgen.js
npm notice 1.7kB  package.json
npm notice 4.2kB  src/index.js
npm notice 3.1kB  src/commands/configure.js
npm notice 25.6kB  package size
npm notice 6.7kB  unpacked size

확인할 것 두 가지:

  1. 의도한 파일만 들어갔는가 — 테스트 파일, 설정 파일이 섞여있지 않은지
  2. 민감한 파일이 빠졌는가.env, API 키, 비밀번호가 포함되지 않았는지

--dry-run 없이 실행하면 .tgz 파일이 생성된다. 직접 압축 풀어서 확인하고 싶을 때 쓴다.


bin 파일 — 실행 권한과 shebang

CLI 도구를 만들 때 bin 파일에 두 가지가 반드시 있어야 한다.

#!/usr/bin/env node
// bin/my-cmd.js

import { run } from '../src/index.js'
run()

#!/usr/bin/env node — 이 한 줄이 없으면 npx로 실행 시 "permission denied" 또는 스크립트가 텍스트로 출력되는 문제가 생긴다.

macOS/Linux에서는 파일 실행 권한도 확인한다.

chmod +x bin/my-cmd.js

Windows는 npm이 자동으로 처리하므로 신경 쓰지 않아도 된다.


ESM vs CommonJS

"type": "module"을 쓰면 .js 파일이 ESM으로 처리된다. 몇 가지 주의사항이 있다.

require()를 쓸 수 없다. import만 사용 가능하다.

// ESM
import { something } from './utils.js'
import fs from 'fs'

// CommonJS (type: module에서는 불가)
const { something } = require('./utils.js')

상대 경로에 확장자를 반드시 붙여야 한다.

// 틀림
import { run } from './src/index'

// 맞음
import { run } from './src/index.js'

__dirname, __filename을 쓸 수 없다. 대신 import.meta.url을 쓴다.

import { fileURLToPath } from 'url'
import { dirname } from 'path'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

배포 전 체크리스트

□ node bin/my-cmd.js --version       정상 출력 확인
□ node bin/my-cmd.js --help          명령어 목록 표시 확인
□ npm pack --dry-run                 포함 파일 목록 확인
□ .env, API 키가 목록에 없는지 확인
□ .gitignore에 node_modules/, .env 포함 확인
□ files 필드로 배포 범위 제한
□ engines로 Node.js 최소 버전 명시
□ README.md에 설치 방법과 사용법 작성
□ LICENSE 파일 포함
□ bin 파일 상단에 #!/usr/bin/env node 확인
□ 버전 번호 확인 (이전 배포 버전보다 높은지)

실제 배포

# npm 로그인 (최초 1회)
npm login

# scoped 패키지는 기본이 private — public으로 배포하려면 플래그 필요
npm publish --access public

# 배포 후 확인
npm info @lukaplayground/my-package

배포 후 72시간 이내에는 npm unpublish로 취소할 수 있다. 이후엔 deprecate만 가능하다.


버전 관리 — semver

# 패치 버전 올리기 (1.0.0 → 1.0.1) — 버그 수정
npm version patch

# 마이너 버전 (1.0.0 → 1.1.0) — 하위 호환 기능 추가
npm version minor

# 메이저 버전 (1.0.0 → 2.0.0) — 하위 호환 깨지는 변경
npm version major

npm version 명령어는 package.json 버전을 올리고 git tag까지 자동으로 만들어준다.


정리

단계 확인 항목
package.json files, bin, engines, type 필드
배포 전 npm pack --dry-run으로 포함 파일 확인
bin 파일 #!/usr/bin/env node shebang 확인
ESM 상대 경로 확장자 .js 필수
배포 npm publish --access public (scoped 패키지)
버전 npm version patch/minor/major

한 번 배포한 버전은 덮어쓸 수 없다. npm pack --dry-run을 습관으로 만들면 실수가 줄어든다.

반응형