패키지 배포하기 (npm publish)

대부분의 자바스크립트 개발자들은 자신의 프로젝트에 주로 다른 패키지를 설치 후 사용하기 위해서 npm(Node Package Manager)을 사용합니다.
이것이 가능한 이유는 고맙게도 다른 개발자들이 어딘가에서 우리가 사용하는 패키지를 열심히 npm에 배포해주고 있기 때문입니다.
오늘은 한번 이러한 개발자의 입장이 되어 자신이 직접 개발한 자바스크립트 패키지를 npm에 배포하는 방법에 대해서 공부해보겠습니다.

npm 저장소

npm을 사용해보신 분이라면 한 번쯤 npm 사이트에 들어가보셨을 것입니다.
보통 이미 사용하고 있는 패키지의 상세한 정보를 확인거나, 새롭게 사용할 패키지를 검색할 때 많이 방문하실 것입니다.
이렇게 우리가 npm 사이트에서 모든 패키지의 정보를 볼 수 있는 이유는 모든 패키지가 한 곳으로 올라오기 때문인데 이 곳은 npm 저장소(registry)라고 불립니다.
우리가 터미널에 npm install <패키지명>를 입력할 때도, 해당 패키지는 npm registry로 부터 내려받아집니다.
즉, npm registry는 자바스크립트 커뮤니티를 위해서 모두에게 인터넷을 통해 공개된 패키지 보관 공간이라고 생각하시면 됩니다.

다른 사람이 올린 패키지를 설치하거나 업데이트할 때는 npm 사이트에 계정이 없어도 되지만, 패키지를 배포하기 위해서는 npm 계정이 있어야 합니다.
따라서 npm 계정이 없으신 분들은 npm 회원가입 페이지에 들어가셔서 계정을 만들 후 이메일 인증까지 진행하시기 바랍니다.

npm 로그인

npm 계정을 만드셨다면 터미널에서 npm login 커맨드를 입력하고 npm 사이트에서 계정을 만들 때 입력했던 개인 정보들을 입력합니다.

1
2
3
$ npm login
(... 생략 ...)
Logged in as daleseo on https://registry.npmjs.org/.

제대로 로그인이 되었다면 npm whoami 커맨드를 입력했을 때, 본인의 username이 출력될 것입니다.

1
2
$ npm whoami
daleseo

패키지명 결정

본인의 패키지를 npm에 배포하려면 먼저 패키지 이름을 정해야 겠죠?
평범한 패키지 이름을 생각하고 계시다면 벌써 누군가가 같은 이름으로 패기지를 배포해놓았을 확률이 매우 높습니다.
왜냐하면 npm 서비스가 2009년에 시작했으니 현재까지 NPM에 등록된 패키지의 수가 어마어마하기 때문입니다.

예를 들어, 저는 이 블로그를 쓰면서 배포할 패키지의 이름을 hello-npm으로 할려고 했었는데요.
무려 7년 전에 다른 분께서 이미 이 패키지명으로 npm에 다른 패키지를 배포하셨더라고요.
이렇게 본인이 사용하려는 패키지명이 기존에 패키지명과 중복되지 않는지는 npm 사이트에서 검색을 하시거나, 터미널에서 npm info <패키지명>을 입력하면 쉽게 확인이 가능합니다.
아래와 같이 패키지의 기본 정보가 나온다면 해당 패키지명이 이미 NPM이 등록되어 있다는 뜻이고, 404 에러가 나면 아직 해당 패키지명이 등록되지 않았기 때문에 사용이 가능하다는 뜻입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ npm info hello-npm

hello-npm@0.0.0 | BSD | deps: 1 | versions: 1
A minimal Node project for The npm Book

dist
.tarball: https://registry.npmjs.org/hello-npm/-/hello-npm-0.0.0.tgz
.shasum: (...생략...)

dependencies:
colors: ~0.6.0-1

maintainers:
- (...생략...)

dist-tags:
first: 0.0.0 latest: 0.0.0

published over a year ago by (...생략...)

그래서 이번에는 hello-npm-1을 패키지명으로 사용하려고 했는데, 이 것도 이미 NPM에 등록되어 있는 패키지명이더라고요. ;;
결국은 어쩔 수 없이 좀 길지만 daleseo-hello-npm이라는 패키지명을 사용하기로 결정하였습니다.

1
2
3
4
5
6
7
8
9
$ npm info daleseo-hello-npm
npm ERR! code E404
npm ERR! 404 Not found : daleseo-hello-npm
npm ERR! 404
npm ERR! 404 'daleseo-hello-npm' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

패키지 생성

실습용으로 daleseo-hello-npm이라는 이름을 가진 초간단 패키지를 생성해보도록 하겠습니다.

1
2
3
$ mkdir daleseo-hello-npm
$ cd daleseo-hello-npm
$ touch package.json

package.json 파일은 모든 npm 패키지에 반드시 있어야 하는 파일입니다.
이 파일이 없으면 npm에 있는 다른 패키지를 설치할 수도 없고, 내가 작성한 패키지를 npm에 배포할 수도 없습니다.

package.json 파일에는 해당 패키지에 대한 기본 정보를 입력하도록 되어 있습니다.
패키지를 배포할 때는 필수적으로 필요한 정보는 패키지명과 버전입니다.
따라서 다음과 같이 nameversion 필드에 본인이 원하는 패키지명과 버전을 입력하면 됩니다.

  • package.json
1
2
3
4
{
"name": "daleseo-hello-npm",
"version": "0.0.0"
}

패키지 배포

자, 이제 놀랍게도 엄밀하게 기술적으로는 패키지를 배포할 준비가 끝났습니다!
터미널에 npm publish를 입력하면 우리가 작성한 패키지는 npm에 패포가 됩니다.
(에러가 난다면, 위에서 설명드린 npm 로그인이 제대로 되었는지 확인 바랍니다.)

1
2
3
4
5
6
7
8
9
10
$ npm publish
npm notice
npm notice 📦 daleseo-hello-npm@0.0.0
npm notice === Tarball Contents ===
npm notice 56B package.json
npm notice === Tarball Details ===
npm notice name: daleseo-hello-npm
npm notice version: 0.0.0
(... 생략 ...)
+ daleseo-hello-npm@0.0.0

막 배포한 패키지는 마찬가지 방밥으로 npm 사이트에 가서 확인하거나, 터미널에서 npm info 커맨드를 치면 확인하실 수 있으십니다.
배포하기 전에는 404 에러가 났었는데, 배포하고 났더니 다음과 같이 패키지의 기본 정보가 출력되고 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
npm info daleseo-hello-npm

daleseo-hello-npm@0.0.0 | Proprietary | deps: none | versions: 1

dist
.tarball: https://registry.npmjs.org/daleseo-hello-npm/-/daleseo-hello-npm-0.0.0.tgz
.shasum: (... 생략 ...)
.integrity: (... 생략 ...)
.unpackedSize: 56 B

maintainers:
- daleseo <dale.seo@gmail.com>

dist-tags:
latest: 0.0.0

published 3 minutes ago by daleseo <dale.seo@gmail.com>

패키지 내용 갱신

여태까지는 패키지 배포에 우선 순위를 두고 설명하느라 배포한 패키지에는 package.json 파일 밖에 없는 상황입니다. ;;
하지만 npm 배포한 패키지에 아무 코드가 없다면 아무도 사용하지 않을테고 그럼 배포한 의미가 없겠지요?

실습 패키지에 index.js라는 자바스크립트 파일을 생성하고 다음과 같이 콘솔에 ‘Hello, npm!’을 출력하는 함수를 추가합니다.

  • index.js
1
2
3
module.exports = function() {
console.log('Hello, npm!');
};

npm에 패키지를 배포할 때는 가급적 README.md 파일도 추가해주는 것이 권장됩니다.
왜냐하면 NPM 사이트에서 패키지를 검색했을 때, README.md 파일에 작성한 내용이 해당 패키지의 메인 화면에 표시되기 때문입니다.

  • README.md
1
2
3
# Hello NPM

Print 'Hello, npm!' in the console.

패키지 재배포

패키지의 갱신된 내용은 npm에 다시 배포를 해야 패키지를 사용하고 있는 사람들이 업데이트를 받을 수 있겠지요?
npm registory 패키지명 뿐만 아니라 버전도 중복을 허용하지 않기 때문에 배포하기 전에 우선 버전을 올려줘야 합니다.
버전을 올릴 때는 package.json 파일을 직접 수정하거나, 터미널에서 npm version <major 또는 minor 또는 patch> 커맨드를 사용합니다.

1
2
$ npm version patch
v0.0.1

patch 옵션을 사용했기 때문에 버전이 0.0.0에서 0.0.1로 올라갔습니다.

1
2
3
4
5
$ cat package.json
{
"name": "daleseo-hello-npm",
"version": "0.0.1"
}

package.json 파일을 열어보면 version 필드의 값이 수정된 것을 알 수 있습니다.

패키지를 재배포할 때는 처음에 패키지를 배포했을 때와 마찬가지로 터미널에서 npm publish 커맨드를 날리면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
$ npm publish
npm notice
npm notice 📦 daleseo-hello-npm@0.0.1
npm notice === Tarball Contents ===
npm notice 56B package.json
npm notice 63B index.js
npm notice 49B README.md
npm notice === Tarball Details ===
npm notice name: daleseo-hello-npm
npm notice version: 0.0.1
(... 생략 ...)
+ daleseo-hello-npm@0.0.1

막 재배포한 패키지는 마찬가지 방밥으로 npm 사이트에 가서 확인하거나, 터미널에서 npm info 커맨드를 치면 확인하실 수 있으십니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ npm info daleseo-hello-npm

daleseo-hello-npm@0.0.1 | Proprietary | deps: none | versions: 2
Print 'Hello, npm!' in the console.

dist
.tarball: https://registry.npmjs.org/daleseo-hello-npm/-/daleseo-hello-npm-0.0.1.tgz
.shasum: (...생략...)
.integrity: (...생략...)
.unpackedSize: 168 B

maintainers:
- daleseo <dale.seo@gmail.com>

dist-tags:
latest: 0.0.1

published 2 minutes ago by daleseo <dale.seo@gmail.com>

배포한 패키지 설치

npm에 배포한 패키지가 다른 프로젝트에서 설치 후에 사용이 가능한지 한 번 확인해보겠습니다.
다음과 같이 퀵하게 테스트용 프로젝트 디렉토리를 하나 생성 후에 npm 패키지로 초기화 합니다.

1
2
3
$ mkdir daleseo-hello-npm-test
$ cd daleseo-hello-npm-test
$ npm init -y

그 다음, 터미널에 npm i 또는 npm install 커맨드를 실행하여 우리가 NPM에 막 배포한 패키지를 설치합니다.

1
2
3
4
$ npm i daleseo-hello-npm
+ daleseo-hello-npm@0.0.1
added 1 package and audited 1 package in 1.189s
found 0 vulnerabilities

설치할 때 패키지 버전을 명시하지 않았기 때문에 최신 버전인 0.0.1이 설치되었습니다.

배포한 패키지 사용

index.js 파일을 생성 후에, 설치한 패키지를 불러온 후에 함수를 호출합니다.

  • index.js
1
2
const helloNpm = require('daleseo-hello-npm');
helloNpm();

터미널에서 막 작성한 index.js 파일을 실행해보면…

1
2
$ node index.js
Hello, npm!

짜잔! 배포한 패키지의 함수가 호출되어 Hello, npm!이 출력되는 것을 확인할 수 있습니다.

참고로, 설치한 패키지는 다음과 같이 node_modules 디렉토리 안에 내려받아져 있습니다.

1
2
3
4
5
6
7
8
9
10
$ tree
.
├── index.js
├── node_modules
│   └── daleseo-hello-npm
│   ├── README.md
│   ├── index.js
│   └── package.json
├── package-lock.json
└── package.json

배포한 패키지 삭제

배포한 패키지는 npm unpublish 커맨드를 이용해서 배포 후 72시간 내에 삭제가 가능합니다.
(그 이후에는 npm 측에 직접 연락하셔서 삭제를 요청하셔야 합니다.)

배포한 패키지의 특정 버전을 삭제하려면 npm unpublish <패키지명>@<버전> 커맨드를 이용합니다.

1
2
$ npm unpublish daleseo-hello-npm@0.0.1
- daleseo-hello-npm@0.0.1

배포한 패키지의 모든 버전을 삭제하려면 npm unpublish <패키지명> -f 커맨드를 이용합니다.

1
2
3
npm unpublish daleseo-hello-npm -f
npm WARN using --force I sure hope you know what you are doing.
- @daleseo-hello-npm

마치면서

지금까지 npm에 패키지를 배포하는 방법에 대해서 실습 프로젝트를 통해서 단계별로 살펴보았습니다.
npm에 본인이 작성한 자바스크립트 패키지를 배포한다는 게 한 번도 안 해본 사람 입장에서는 어렵게 느껴질 수도 있는데요.
이 포스팅을 따라 한 번 따라해보시고 생각했던 것보다 훨씬 간단하고 쉽구나하고 느끼셨으면 좋겠습니다.

공유하기