Post

[JavaScript] npm (node package manager)

[JavaScript] npm (node package manager)

npm(node package manager)

npm(node package manager)은 자바스크립트 패키지 매니저다. Node.js에서 사용할 수 있는 모듈을 패키지화 하여 모아둔 저장소 역할과 패키지 및 관리를 위한 CLI(Command Line interface)를 제공한다. 자신이 작성한 패키지를 공개할 수도 있고 필요한 패키지를 검색하여 재사용할 수도 있다.

패키지 설치

Node.js에서 사용할 수 있는 모듈 패키지를 설치할 때에는 npm install 명령어 뒤에 설치할 패키지 이름을 지정한다.

1
2
3
$ npm [명령어] [타겟 모듈 이름] [옵션]

$ npm install <package>

지역 설치 / 전역 설치

npm install 명령어에는 지역(local) 설치와 전역(global) 설치 옵션이 있다.

옵션을 별도로 지정하지 않으면 지역으로 설치되며, 프로젝트 루트 디렉토리에 node_modules 디렉토리가 자동 생성되고, 그 안에 패키지가 설치된다, 지역으로 설치된 패키지는 해당 프로젝트 내에서만 사용할 수 있다.

1
2
# 지역 설치
$ npm install <package>

전역에 패키지를 설치하려면 npm install 명령어에 -g 옵션을 추가한다. 모든 프로젝트가 공통 사용하는 패키지는 지역으로 설치하지 않고 전역에 설치한다.

1
2
# 전역 설치
$ npm install -g <package>

전역에 설치된 패키지는 OS에 따라 설치 장소가 다르다.

  • mac: /usr/local/lib/node_modules
  • win: c:\Users\%USERNAME%\AppData\Roaming\npm\node_modules

전역으로 모듈을 설치하게 된다면, 설치한 모듈명을 명령어로 사용할 수 있게 된다.

1
2
$ npm install -g nodemon
$ nodemon <package>

다만 전역으로 설치 시 package.json에 기록이 안된다는 단점이 있어 협업에서 마이너스로 작용한다.
따라서 -D 옵션을 통해 devDependencies에 깔고, npx 명령어를 통해 글로벌하게 실행하는 방식을 많이 사용한다.

1
2
$ npm i -D nodemon
$ npx nodemon <package>

package.json과 의존성 관리

Node.js 프로젝트에서는 많은 패키지를 사용하게 되고 패키지의 버전도 빈번하게 업데이트 되므로 프로젝트가 의존하고 있는 패키지를 일괄 관리할 필요가 있다.

npm은 package.json 파일을 통해서 프로젝트 정보와 패키지의 의존성(dependency)을 관리한다.
이미 작성된 pcakage.json이 있다면 팀 내에 배포하여 동일한 개발 환경을 빠르게 구축할 수 있는 장점이 있다.

package.json은 java의 pom.xml과 비슷한 역할을 한다.
package.json을 생성하려면 프로젝트 루트에서 npm init 명령어를 실행한다.

일단 기본 설정값으로 생성된 package.json 파일을 수정하는 방벙비 더 편리할 수 있으므로 npm init -y 명령어를 실행한다 그러면 기본 설정값으로 package.json 파일을 생성한다.

1
$ npm init -y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "node-emoji": "^1.10.0"
  },
  "devDependencies": {},
  "script": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  • name
    • 프로젝트 이름으로 가장 중요하다.
    • 중앙 저장소에 배포할 때 version과 함께 필수 항목이다.
    • url로 사용되고, 설치할 때 디렉토리 이름이 되기 때문에 url이나 디렉토리에서 쓸 수 없는 이름을 사용하면 안된다.
    • 또한, 이름에 node나 js가 들어가면 안된다.
    • name은 214자 보다 짧아야 하며, 점(.)이나 밑줄(_)로 시작할 수 없다.
    • 대문자를 포함해서는 안되며, require() 함수의 인수로 사용되며 짧고 알기 쉬운 것으로 짓는 것이 좋다.
  • version
    • 프로젝트 버전을 정의한다. 3단계 버전을 사용하며, -로 태그 이름을 적을 수 있다.
  • description
    • 프로젝트 설명으로, 문자열로 기술한다.
    • npm search로 검색된 리스트에 표시되기 때문에 사람들이 패키지를 찾아내고 이해하는 데 도움이 된다.
  • keywords
    • 프로젝트를 검색할 때 참조되는 키워드다.
    • description과 마찬가지로 npm search로 검색된 리스트에 표시된다.
  • homepage
    • 프로젝트 홈페이지 주소다.
    • url 항목과는 다르며, url을 설정하면 예상치 못한 움직임을 하게 되므로 주의한다.
  • author
    • 프로젝트 작성자 정보로, 한 사람만을 지정한다. JSON 형식으로 name, email, url 옵션을 포함한다.
  • contributors
    • 프로젝트에 참여한 공헌자 정보로, 여러 사람을 배열로 지정할 수 있다.
  • repository
    • 프로젝트의 소스 코드를 저장한 저장소의 정보이다.
    • 소스 코드에 참여하고자 하는 사람들에게 도움이 될 수 있다.
    • 프로젝트 홈페이지 url을 명시해서는 안된다.
  • scripts
    • 프로젝트에서 자주 실행해야 하는 명령어를 script로 작성해두면 npm 명령어로 실행 가능하다.
  • config
    • 소스 코드에서 config 필드에 있는 값을 환경 변수처럼 사용할 수 있다.
  • private
    • 이 값을 true로 작성하면 중앙 저장소로 저장하지 않는다.
  • dependencies
    • 서비스를 배포할 때 쓰이는 모듈을 관리하는 부분이다.
    • 이 프로젝트가 어떤 확장 모듈을 요구하는지 정리할 수 있다.
    • 일반적으로 package.json에서 가장 많은 정보가 입력되는 곳이다.
    • 어플리케이션을 설치할 때 이 내용을 참조하여 필요한 확장 모듈을 자동으로 설치한다.
    • 따라서 개발한 어플리케이션이 특정한 확장 모듈을 사용한다면 여기에 꼭 명시를 해줘야 한다.
    • 또한, npm install 명령은 여기에 포함된 모든 확장 모듈을 설치하게 된다.
  • devDependencies
    • 개발할 때만 사용하는 확장 모듈을 관리한다.
  • engine
    • 실항 가능한 노드 버전의 범위를 결정한다.

package.json에서 가장 중요한 항목은 nameversion이다. 이것은 패키지 고유성을 판단하므로 생략할 수 없다.

그리고 dependencies 항목에는 해당 프로젝트가 의존하는 패키지들의 이름과 버전을 명시한다. 여기서 의존하는 패키지란 해당 프로젝트에서 참조하는 모듈을 의미한다.

프로젝트를 진행할 때는 이미 만들어진 여러 패키지를 참조해서 사용하는데, package.json 파일의 dependencies 항목에 해당 패키지의 이름과 버전을 명시함으로써 의존성을 설정한다.

devDependencies에는 개발 시에만 사용하는 개발용 의존 패키지를 명시한다.
예를 들어 TypeScript와 같은 트랜스파일러는 개발 단계에서만 필요하고 배포할 필요는 없으므로 devDependencies에 포함시킨다.

npm install 명령어에 –save-dev(축약형 -D) 옵션을 사용하면 패키지 설치와 함께 package.json의 devDependencies에 설치된 패키지와 버전이 기록된다.

1
2
$ npm i -D <package>
$ npm install --save-dev <package>

package-lock.json

package.json에서 설치한 모듈의 dependencies들을 정확하게 하나하나 명시해 놓은 것이 package-lock.json이다.
버전 문제가 생기는 것 빼고는 잘 건들지 않는다.

Semantic Versioning (유의적 버전)

npm install 명령어의 패키지명 뒤에 @버전을 추가하면 패키지 버전을 지정하여 설치할 수 있다.

1
$ npm i webpack@1.5.0
1
2
3
4
5
6
7
...
{
  "dependencies": {
    "webpack": "^1.5.0"
  }
}
...

이 때 package.json의 dependencies에 새롭게 추가한 패키지가 추가되고 버전 앞에 ^(캐럿)이 추가된 것을 확인할 수 있다.
이것은 패키지 버전을 지정하였을 때 뿐만 아니라 –save-exact 옵션을 지정하지 않으면 기본적으로 추가되는 것이다.

이 ^(캐럿)은 이후 해당 패키지의 버전이 업데이트 되었을 경우, 마이너 버전 범위 내에서 업데이트를 허용한다는 의미다. 즉, 나는 Major 버전만 올리지 않고 사용하겠다 라는 말이다.

npm install 명령어에 --save-exact 옵션을 지정하면 설치된 버전을 벙뮈 지정 없이 기록한다.

버전 정보는 메이저 버전 번호, 마이너 버전 번호, 패치 버전 번호로 구성된다.

1.10.7
[ 1 :Major ] 하위 호환이 되지 않는 변경 사항
[ 10 : Minor ] 하위 호환이 되는 변경 사항
[ 7 : Patch ] 간단한 버그 수정

Major(주 버전), Minor(부 버전), Patch(수 버전)

  • Major하위 버전과 호환되지 않는 수정 사항이 생겼을 때 올림
  • Minor하위 버전과 호환되는 수정 사항이 생겼을 때 올림
  • Patch기능에 버그를 해결했을 때 올림

버전 정보 앞에는 기호를 부여하여 업데이트 범위를 지정할 수 있다. 기술 방식은 아래와 같다.

  • version: 명시된 version과 일치
  • >version: 명시된 version보다 높은 버전
  • >=version: 명시된 version과 같거나 높은 버전
  • <version: 명시된 version보다 낮은 버전
  • <=version: 명시된 version과 같거나 낮은 버전
  • ~version: 명시된 version과 근사한 버전
  • ^version: 명시된 version과 호환되는 버전
  • @latest: 최신 버전을 설치하라는 의미 $ npm i express@latest
  • @next: 실험적인 버전

각 버전마다 부가적으로 알파/베타/RC 버전이 존재할 수도 있음 (1.1.1-alpha, 2.0.0-beta, 2.0.0-rc.0)

~(틸트)와 ^(캐럿)의 차이는 아래와 같다.

  • ~(틸트)는 패치 버전 범위 내에서 업데이트한다.
    • ~0.0.1 : 0.0.1 <= version < 0.1.0
    • ~0.1.1 : 0.1.1 <= version < 0.2.0
  • ^(캐럿)은 마이너 버전 범위 내에서 업데이트 한다.
    • ^1.0.2 : 1.0.2 <= version < 2.0

자주 사용하는 npm 명령어

package.json 생성

1
2
$ npm init
$ npm init -y

패키지 설치

1
2
3
4
5
6
7
8
9
10
11
# 로컬 설치
$ npm i <package>

# 전역 설치
$ npm i -g <package>

# 개발 전용 설치
$ npm i -D <package>

# package.json에 명시된 모든 패키지 설치
$ npm i

패키지 제거

1
2
3
4
5
# 로컬/개발 패키지 제거
$ npm uninstall <package>

# 전역 패키지 제거
$ npm uninstall -g <package>

패키지 업데이트

1
2
$ npm update <package>
$ npm update -g <package>

패키지 목록

현재 개발중인 어플리케이션에 설치된 확장 모듈을 확인하려면 터미널에 아래 명령어를 입력한다.
설치한 모듈이 너무 많아 package-lock.json에서 확인할 수 없을 때 유용하게 쓰일 수 있다.

1
2
3
4
$ npm list
$ npm ls

$ npm ls <package>

아래 이미지 처럼 상속을 자세히 나열해서 표시해준다.

alt text https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-%EB%85%B8%EB%93%9C-npmnode-package-manager

전역 설치 패키지 확인

1
2
3
$ npm list -g
$ npm ls -g
$ npm ls -g --depth=0

package.json script 프로퍼티의 실행

1
2
3
4
$ npm start

# start 이외의 script 실행
$ npm run build

전역 패키지 설치 폴더 확인

1
2
3
4
5
$ npm root -g
> /usr/local/lib/node_modules

# 파인더 오픈
$ open /usr/local/lib/node_modules

패키지 정보 참조

1
2
3
4
$ npm view <package>

# 패키지의 세부 정보 파악
$ npm info <package>

npm 명령어 설명 참조

1
$ npm help <command>

해당 패키지 버전 설치

1
2
3
4
5
# 해당 버전 설치
$ npm install express@4.1.0

# 최신 버전 설치
$ npm install express@latest

패키지 버전 변화 확인

1
2
3
4
5
# 버전 확인
$ npm -v

# 어떤 패키지에 기능 변화가 생겼는지 확인
$ npm outdated

alt text https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-%EB%85%B8%EB%93%9C-npmnode-package-manager

패키지 버전 올림 (업데이트)

: package.json의 버전을 올림 (git에 커밋도 함)

1
2
3
4
5
6
7
8
# 패치 버전이 올라감
$ npm version patch

# 마이너 버전이 올라감
$ npm version minor

# 메이저 버전이 올라감
$ npm version major

패키지 배포

1
2
3
4
5
6
7
8
9
# 패키지를 설치할 때 경고 메시지를 띄우게 함 (오류가 있는 패키지에 적용)
$ npm deprecate [패키지명][버전] [메시지]

# 자신이 만든 패키지를 배포
$ npm publish

# 자신이 만든 패키지를 배포 중단 (배포 후 72시간 내에만 가능)
# 다른 사람이 내 패키지를 사용하고 있는데 배포가 중단되면 문제가 생기기 때문
$ npm unpublish --force

패키지 검색

1
2
# npm 패키지를 검색할 수 있음. (npmjs.com에서도 가능)
$ npm search <검색어>

사용자 확인

1
2
3
4
5
6
7
8
# npm에 로그인을 하기 위한 명령어 (npmjs.com에서 회원가입 필요)
$ npm login

# 현재 사용자가 누구인지 알려줌
$ npm whoami

# 로그인한 계정을 로그아웃
$ npm logout


참고
This post is licensed under CC BY 4.0 by the author.

Trending Tags