자주 사용되는 npm 커맨드 (+npx)

백앤드 개발을 하든 프런트앤드 개발을 하든 자바스크립트 프로젝트에서 NPM(Node Package Manager)을 사용하는 것은 거의 필수가 되었습니다. 이번 포스트에서는 실무에서 자주 사용되는 NPM 커맨드들에 대해서 살펴보겠습니다.

프로젝트 생성

npm init 커맨드를 사용하면 현재 디렉토리에 NPM 기반으로 프로젝트를 생성할 수 있습니다. 커맨드를 실행하면 패키지 이름, 버전, 설명 등등을 입력하게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (hello-npm)
version: (1.0.0)
description:

프로젝트를 생성할 때 이러한 정보들을 일일이 입력하는 게 귀찮게 느껴질 수 있습니다. 이 때는 --yes-y 옵션을 주시면 디폴트 값으로 프로젝트가 생성이 됩니다.

1
2
$ npm init -y
Wrote to /temp/hello-npm/package.json:

이렇게 NPM 프로젝트를 생성하고 나면 디렉토리에 package.json 파일이 생성됩니다. 사실 NPM 프로젝트라는 게 별다른게 아니라 package.json 파일을 가진 모든 디렉토리를 NPM 프로젝트라고 볼 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ls
package.json
$ hello-npm cat package.json
{
"name": "hello-npm",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

신규 패키지 설치

NPM을 사용하는 가장 큰 이유는 NPM에 등록되어 있는 무궁무진한 외부 패키지를 설치하기 위해서 일 것 입니다. npm install 또는 npm i 커맨드를 사용하면 원하시는 패키지를 설치할 수 있습니다.

1
2
3
4
$ npm i lodash
+ lodash@4.17.10
added 1 package from 2 contributors and audited 1 package in 0.914s
found 0 vulnerabilities

lodash라는 라이브러리를 설치해보았습니다. 설치가 끝나면 node_modules 디렉토리가 생기고 그 안에 lodash 디렉토리가 생겼음을 알 수 있습니다. NPM이 lodash 패키지의 파일들을 이 디렉토리 안으로 다운로드 받아놓았습니다.

1
2
$ ls node_modules
lodash

또한 package.json 파일을 열어보면 dependencies 속성에 해당 패키지의 이름과 버전이 추가되었음을 알 수 있습니다. 이는 다른 개발자들과 협업 시 외부 패키지는 제외하고 프로젝트 코드만 공유할 수 있도록 해줍니다. 이 부분은 아래에서 다시 살펴보도록 하겠습니다.

  • package.json
1
2
3
"dependencies": {
"lodash": "^4.17.10"
}

lodash처럼 런타임에 필요한 패키지도 있지만 개발할 때만 필요한 패키지도 있습니다. 이러한 패키지는 --save-dev 또는 -D 옵션을 줘서 개발 의존성 모드로 설치해야 합니다.

1
$ npm i -D mocha

mocha라는 테스트 라이브러리를 개발 의존성으로 설치해보았습니다. 테스트 라이브러리는 상용 빌드에 포함될 필요가 없기 때문입니다. 설치 후 node_modules 디렉토리를 열어보면 상당히 많은 디렉토리들이 추가되어 있음을 알 수 있습니다. mocha처럼 어떤 패키지는 다른 패키지들에 의존해서 작동합니다. 그리고 mocha가 의존하는 패키지들은 또 다른 패키지에 의존할 수 있습니다. 이렇게 NPM은 직접 의존하고 있는 패키지 뿐만 아니라 간접적으로 의존하고 있는 패키지(transitive dependency)까지 모조리 다운받아 줍니다.

개발 의존성으로 설치된 패키지는 package.json 파일에서 devDependencies 속성에 들어가게 됩니다.

  • package.json
1
2
3
"devDependencies": {
"mocha": "^5.2.0"
}

패키지 전역 설치

간혹 패키지를 현재 디렉토리 뿐만 아니라 어디서나 실행할 수 있도록 전역으로 설치해야 할 때가 있습니다. 이러한 패키지는 --global 또는 -g 옵션을 줘서 설치합니다.

1
$ npm i -g http-server

http-server라는 CLI 도구를 전역으로 설치해보았습니다. http-server는 현재 디렉토리에 있는 파일을 웹처럼 서비스해주는 간단한 HTTP 서버입니다. 설치가 끝난 후 터미널에 http-server라고 입력해보면 8080 포트로 HTTP 서버가 구동되는 것을 볼 수 있습니다.

1
2
3
4
5
6
$ http-server
Starting up http-server, serving ./
Available on:
http://127.0.0.1:8080
http://192.168.0.3:8080
Hit CTRL-C to stop the server

하지만 node_modules 디렉토리나 package.json 파일에는 아무 변화가 일어나지 않습니다. 이 패키지는 전역으로 설치했기 때문에 이 프로젝트에만 국한되지 않기 때문입니다. 참고로 전역 패키지들은 보통 노드JS가 설치된 디렉토리 내의 lib/node_modules에서 찾을 수 있습니다. (또는 터미널에 npm bin -g라고 입력하면 정확한 패키지 전역 설치 디렉토리 경로가 출력됩니다.)

기존 패키지 일괄 설치

위에서 잠깐 언급했던 것 처럼 Git과 같은 소스 관리 시스템에 NPM 프로젝트를 올려놓을 때 일반적으로 node_modules 디렉토리는 제외시키는 경우가 일반적입니다. 그래서 Git 리파지토리를 클론 후에는 최초 1회 기존에 설치된 패키지들을 설치해줘야 합니다. 위에서 살펴본 것 처럼 package.json 파일에 설치된 패키지에 대한 메타 데이터가 담겨있기 때문에 기존에 설치되어 있던 모든 패키지를 한 번에 설치할 수 있습니다.

1
2
3
$ git clone <패키지 이름>
$ cd <패키지 이름>
$ npm i

위와 같이 npm i 커맨드 뒤에 패키지명을 붙이지 않으면 package.json 파일에 등록되어 있는 모든 패키지를 설치해줍니다.

설치된 패키지 확인

기존에 설치된 패키지를 확인할 때는 보통 package.json 파일을 열어 dependenciesdevDependencies 항목을 확인하게 됩니다. 하지만 많은 패키지들이 내부적으로 또 다른 패키지들에 의존하고 있기 때문에 가끔 전체적인 의존성 트리를 확인하고 싶을 때가 생깁니다. 이럴 때는 npm ls 커맨드를 사용하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ npm ls
hello-npm@1.0.0 /temp/hello-npm
├── lodash@4.17.10
└─┬ mocha@5.2.0
├── browser-stdout@1.3.1
├── commander@2.15.1
├─┬ debug@3.1.0
│ └── ms@2.0.0
├── diff@3.5.0
├── escape-string-regexp@1.0.5
├─┬ glob@7.1.2
│ ├── fs.realpath@1.0.0
│ ├─┬ inflight@1.0.6
│ │ ├── once@1.4.0 deduped
│ │ └── wrappy@1.0.2
│ ├── inherits@2.0.3
│ ├── minimatch@3.0.4 deduped
│ ├─┬ once@1.4.0
│ │ └── wrappy@1.0.2 deduped
│ └── path-is-absolute@1.0.1
├── growl@1.10.5
├── he@1.1.1
├─┬ minimatch@3.0.4
│ └─┬ brace-expansion@1.1.11
│ ├── balanced-match@1.0.0
│ └── concat-map@0.0.1
├─┬ mkdirp@0.5.1
│ └── minimist@0.0.8
└─┬ supports-color@5.4.0
└── has-flag@3.0.0

패키지 제거

설치된 패키지를 제거하려면 어떻게 해야될까요?

npm uninstall 또는 npm r 커맨드를 사용하면 원하시는 패키지를 프로젝트로 부터 제거할 수 있습니다.

1
$ npm r mocha

위에서 설치한 mocha 라이브러리를 제거해보았습니다. package.json 파일을 열어보면 제거한 패키지에 대한 메타 데이터도 지워졌음을 알 수 있습니다.

  • package.json
1
"devDependencies": {}

전역으로 설치한 패키지는 설치할 때와 동일하게 --global 또는 -g 옵션을 줘서 제거하면 됩니다.

1
2
3
4
$ npm r -g http-server
removed 25 packages in 0.261s
$ http-server
zsh: command not found: http-server

위에서 설치했던 http-server 라이브러리를 제거 후에 터미널에 http-server라고 입력해보면 해당 커맨드를 찾지 못하는 것을 알 수 있습니다.

패키지 무설치 실행 (NPX)

NPM 5.2.0 버전 부터는 npx라는 유용한 커맨드가 추가되어 구지 패키지를 설치하지 않고도 실행할 수 있는 방법이 생겼습니다. 방대한 NPM 라이브러리들을 설치의 부담없이 1회성으로 즉석해서 실행해볼 수 있기 때문에 최근에 많이 사용되고 있습니다.

예를 들어 http-server 패키지를 프로젝트나 전역에 설치하지 않고 다음과 같이 npx 커맨드 뒤에 패키지명만 붙여서 실행해볼 수 있습니다.

1
2
3
4
5
6
7
$ npx http-server
npx: installed 25 in 3.28s
Starting up http-server, serving ./
Available on:
http://127.0.0.1:8080
http://10.212.5.70:8080
Hit CTRL-C to stop the server

하지만 실행 후에도 $PATH 환경변수에 해당 커맨드를 추가되지 않으며 설치 파일을 전역 설치 디렉토리에도 남기지 않습니다. 또한 프로젝트의 node_modules 디렉토리나 package.json 파일에도 아무 변화가 일어나지 않습니다.

스크립트 실행

NPM 프로젝트를 테스트나 구동, 빌드할 때 반복적으로 실행해야하는 스크립트를 package.json 파일에 등록해두고 npm run 커맨드를 이용해서 간편하게 실행시킬 수 있습니다.

예를 들어 어떤 NPM 프로젝트의 package.json에 다음과 같이 3개의 스크립트가 등록되어 있다고 가정해봅시다.

  • package.json
1
2
3
4
5
"scripts": {
"test": "mocha --compilers js:babel-register",
"start": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}

빌드를 실행하려면 npm run 커맨드 뒤에 스크립트 이름을 붙여서 터미널에 입력하면 됩니다.

1
$ npm run build

이는 아래 커맨드를 직접 입력해서 실행한 것과 같이 효과를 발생시킵니다.

1
$ ./node_modules/mocha --compilers js:babel-register

예외적으로 teststart 스크립트의 경우, 많이 사용되기 때문에 run을 생략하고 실행시킬 수 있습니다.

1
$ npm test
1
$ npm start

이상으로 자주 사용되는 NPM 커맨드에 대해서 알아보았습니다. 이 정도만 숙지하고 계시면 큰 어려움 없이 NPM을 사용해서 자바스크립트 개발을 하실 수 있으실 것입니다.

참고

공유하기