Skip to content

Instantly share code, notes, and snippets.

@hjsix2
Last active September 13, 2016 06:46
Show Gist options
  • Save hjsix2/eb4ad67d2b8fd5c117bc33151d657e25 to your computer and use it in GitHub Desktop.
Save hjsix2/eb4ad67d2b8fd5c117bc33151d657e25 to your computer and use it in GitHub Desktop.

NodeJS - Package.json

name

package.json에서 가장 중요한 항복은 nameversion이다. 필수로 입력되어야 하며 이 항목들이 빠지면 당신의 패키지는 설치할 수 없다. name과 version을 통해 각 패키지의 고유성을 판별하게 된다. 따라서 패키지의 내용을 변경하려면 version을 변경해야만 한다.

규칙

  • 반드시 214자보다 짧아야 한다. 이는 scoped package의 scope를 포함한다.
  • . 이나 밑줄 _로 시작할 수 없다.
  • 대문자를 포함해서는 안 된다.
  • URL의 일부분이자, 커맨드 라인의 인수이고 폴더명이다. 따라서 모든 URL-safe 하지 않은 name은 거부된다.

조언

  • Node의 코어 모듈과 같은 이름을 사용하지 않는다.
  • name에 node 또는 js를 넣지 않는다. package.json을 쓰고 있는 시점에서 이미 JavaScript라는 것을 알 수 있고 engines 항목에서 실행기반(engine)을 지정할 수 있다.
  • name은 JavaScript 파일 내에서 require() 함수의 인수로 사용되므로 짧게 하면서도 알기 쉬운 것으로 짓는 것이 좋다.
  • 설정 전에 같은 이름이 이미 있는지 확인하려면 npm registry

name은 scope에 의해 접두어가 추가될 수 있는데, 예를 들어 @hjsix2/mypackage와 같은 형태가 될 수 있다.

version

version은 반드시 npm의 디펜던시에 포함된 node-semver로 parsing 가능해야 한다. version number와 range에 대한 더 자세한 정보는 semve항목을 참고 한다.

description

설명을 문자열로 기술한다. npm search로 검색된 리스트에 표시되기 때문에 사람들이 당신이 만든 패키지를 찾아 내고 이해하는데 도움이 된다.

keywords

키워드를 문자열 배열로 설명한다. npm search로 검색된 리스트에 표시되기 때문에 사람들이 당신이 만든 패키지를 찾아 내고 이해하는데 도움이 된다.

homepage

프로젝트 홈페이지가 있을 경우 이 항목에 입력한다. 주의: 이것은 'url'항목과는 다르다. 만약 url을 설정하면 그것은 외부에 설치된 패키지 소스로 리다아렉션 되고, 예상치 못한 움직임을 유발한다.

bugs

프로젝트의 이슈와 버그 트래킹을 볼 수 있는 url과 이슈를 알릴 email 주소를 입력한다. 이 항목들은 패키지 사용자가 문제에 직면했을 때 도움을 주기 위함이다.

"bugs": {
    "url": "http://github.com/owner/project/issues",
    "email": "[email protected]"
}

url이나 email 중 하나만 적용 할 수 있고, url 만 지정하면 객체가 아니라 단순히 문자열을 bugs 항목에 지정할 수도 있다. url을 지정하는 경우에는 npm bugs 명령을 사용할 수 있다.

license

패키지 사용자들이 당신이 만든 패키지를 사용하기 위해 어떻게 권한을 얻는지, 또 어떤 금기 사항이 있는지 알게하기 위해 라이센스를 명시해야 한다. 가장 간단한 방법은 BSD-3-Clause 나 MIT 같은 일반적인 라이센스의 표준 SPDX ID를 아래와 같이 지정하는 것이다.

"license": "BSD-3-Clause"

https://spdx.org/licenses/ 에서 SPDX 라이센스 아이디 전체 리스트를 볼 수 있다. OSI 에서 승인한 것들 중 하나를 사용하는 것이 이상적이다.

만약 패키지가 여러 개의 라이센스 아래에 있다면, 아래와 같이 SPDX license expression syntax version 2.0 string 을 사용해서 표현한다.

"license" : "(ISC OR GPL-3.0)"

만약 SPDX 식별자로 할당되지 않은 라이센스를 사용한다면, 아래와 같이 SPDX 표현을 따라 해당 라이센스를 지정해준다.

"license" : "SEE LICENSE IN <filename>"

<filename> 에 명시된 파일은 패키지의 톱레벨에 포함시킨다.

오래된 패키지 중 일부는 licenses 라는 속성으로 라이센스들의 목록을 가지고 있었지만, 이 방식은 현재 deprecated 되었다.

// 아래의 방식은 더이상 사용하지 않는다.
"license" : {
    "type" : "ISC",
    "url" : "http://opensource.org/licenses/ISC"
}


// 아래의 방식은 더이상 사용하지 않는다.
"licenses" : [{
    "type": "MIT",
    "url": "http://www.opensource.org/licenses/mit-license.php"
},
{
    "type": "Apache-2.0",
    "url": "http://opensource.org/licenses/apache2.0.php"
}]

대신에 SPDX 표현을 아래와 같이 사용해야 한다.

"license": "ISC"

"license": "(MIT OR Apache-2.0)"

마지막으로 비공개로 사용하거나 어떤 조건에서도 패키지를 퍼블리싱하지 않을 경우 아래와 같이 명시해준다.

"license": "UNLICENSED"

이런 경우, "private": true 로 설정함으로써 미연에 퍼블리싱하게 되는 것을 막아줄 수도 있다.

people fields: author, contributors

author 는 한 사람만을 지정하고, contributors 는 여러 사람을 배열로 지정한다. 각 사람은 아래와 같이 필수적으로 name을 포함하고 선택적으로 email 과 url 값을 갖는다.

"author": {
    "name" : "Barney Rubble",
    "email" : "[email protected]",
    "url" : "http://barnyrubble.tumblr.com/"
}

또는 하나의 스트링으로 아래와 같이 줄여서 입력하면 npm이 이를 파싱하게 된다.

"author": "Barney Rubble <[email protected]> (http://barnyrubble.tumblr.com/)"

npm은 또한 maintainers 라는 필드에 당신의 npm 사용자 정보를 설정한다.

files

files 항목은 프로젝트에 포함된 파일의 배열이다. 폴더 이름을 지정하면 폴더 안의 파일도 포함된다. (물론, 다른 설정애 의해 해당 파일들이 무시되지 않는 경우)

또한 .npmignore 라는 파일을 패키지의 루트 혹은 하위 폴더에 둘 수 있는데, 이 파일에 기록된 파일들은 "files"의 배열로 지정되어 있었다고 해도 대상에서 제외된다. .npmignore 파일은 .gitignore 파일과 유사하다고 보면 된다.

다음의 파일들은 설정에 관계없이 항상 포함된다.

  • package.json
  • README
  • CHANGELOG
  • LICENSE 또는 LICENCE

반대로, 일부 파일들은 항상 무시된다.

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • *.swp
  • .DS_Store
  • ._*
  • npm-debug.log

main

main 항목은 당신의 프로그램의 시작점이 되는 모듈의 ID 이다. 즉, 'foo' 라는 패키지가 있다면, 이 패키지을 사용자가 설치 한 뒤, require("foo") 를 실행했을 때 main으로 지정한 모듈의 exports 객체가 반환된다.

모듈 ID는 패키지 루트에 상대적인 경로를 지정해야 한다. 대부분의 모듈에 있어서 메인 스크립트를 갖는 것은 유용하지만 종종 그렇지 않을수도 있다.

bin

많은 패키지는 PATH에 설치되는 하나 이상의 실행 파일을 가지고 있다. npm에서는 이를 매우 쉽게 구현할 수 있다. (실제로 이 기능은 npm을 설치하는 데에도 사용되고 있다.)

실행할 수 있는 패키지를 만들기 위해선 package.json 파일에 bin 항목을 제공해야 한다. 패키지 설치 시에, npm 은 bin 항목에 기술된 파일의 심볼릭 링크를 global install인 경우 prefix/bin 에, local install인 경우 ./node_modules/.bin/ 에 생성하게 된다.

예를 들어, myapp은 아래와 같이 bin 항목이 지정되어 있다.

"bin": { "myapp": "./cli.js" }

그래서 myapp을 설치할 때, cli.js 파일에 대한 심볼릭 링크가 /usr/local/bin/myapp 에 만들어진다.

만약, 하나의 실행 파일만 가지고 있다면, 실행 파일의 이름은 패키지의 이름과 같게 되고, 그렇게 않다면 아래와 같이 각각의 실행 파일의 이름을 bin 항목에 지정해 주어야 한다.

"name": "my-program",
"version": "1.2.5",
"bin": {
    "my-program": "./path/to/program"
}

directories

CommonJS Packages 스펙에는 directories 개체를 사용해서 패키지 구성을 나타낼 수 있다. npm의 package.json 을 보면 doc, lib와 man 으로 이루어진 디렉토리 구성을 확인 할 수 있다.

미래에는, 이러한 정보가 더 창의적인 목적으로 이용될지도 모른다.

directories.lib

모듈의 라이브러리가 어디에 있는지 보여준다. lib 폴더에 특별한 일을 하지는 않지만 메타 데이터로 유용하다.

directories.bin

만약 directories.bin 로 bin 을 지정하면, 해당 디렉토리의 모든 파일이 실행 파일로 추가된다. bin 이 동작하는 방식에 의해, bin 과 directories.bin 을 모두 지정하는 것은 오류이다. 개개의 파일을 지정하고 싶다면 bin을 특정 폴더 아래의 모든 파일을 bin 으로 지정하고 싶다면 directories.bin을 사용하는 것이 좋다.

directories.man

man 문서들이 위치한 폴더를 가리킨다. "man" 배열을 만드는 것보다 간편하다.

directories.doc

마크다운 파일들을 여기에 위치시킨다. 언젠가는 이 파일들이 멋지게 표시될 것이다.

directories.example

예제 파일들을 여기에 위치시킨다. 언젠가는 이 파일들이 멋지게 표시될 것이다.

repository

소스 코드가 관리되는 저장소 위치를 지정한다. 소스 코드에 참여하고자하는 사람들에게 도움이 될 수 있다. 만약 git 저장소가 github 이라면 npm docs 명령으로 찾을 수 있다.

"repository": {
    "type": "git",
    "url": "http://github.com/npm/npm.git"
}

"repository": {
    "type": "svn",
    "url": "http://v8.googlecode.com/svn/trunk/"
}

URL은 특별한 조작없이 VCS 프로그램에서 바로 다뤄질 수 있도록 오픈되어 있어야 한다. 컴퓨터를 위한 부분이므로, 프로젝트의 홈페이지 URL을 명시해서는 안된다.

scripts

script 항목은 패키지의 생명주기 중 다양한 타이밍에서 실행되는 script 명령들을 포함하고 있는 사전이다. scripts 항목 객체에서 키는 이벤트이고, 값은 이때 실행될 커맨드이다.

자세한 내용은 npm-scripts (https://docs.npmjs.com/misc/scripts) 를 참조한다.

config

config 객체는 패키지의 버전에 관계없이 패키지 스크립트에서 사용될 수 있는 설정 정보이다. 예를 들어, 패키지에 다음과 같은 값이 설정되어 있다고 하면,

"name": "foo",
"config": {
    "port": "8080"
}

start 명령을 실행할 때 npm_package_config_port 를 참조할 수 있게 된다. 다음 명령으로 사용자가 이를 덮어 쓸 수 있다.

npm config set foo:port 8001

자세한 내용은 npm-config 및 npm-scripts 를 참조한다

dependencies

의존성을 규정하는 것은 패키지의 이름과 해당 패키지의 버전 범위를 지정한 객체를 통해 이루어진다. 버전 범위는 하나 혹은 여러개의 공백으로 분리된 설명자 문자열이다. 의존성은 tarball 이나 git URL로도 지정될 수 있다.

테스트 관련 모듈이나 트랜스 파일러 관련 모듈을 dependencies 개체에 추가하면 안된다. 운영이 아닌 개발 단계에서만 필요한 의존성 모듈들은 devDependencies 에 설치해야 한다. 자세한 것은 devDependencies 항목을 참고하자.

semver 를 참고하면 버전 범위를 지정하는 방법에 대해 알 수 있다.

  • version : 명시한 version 과 일치해야 한다.
  • version : 명시한 version 보다 높아야 한다.

  • =version

  • <version
  • <=version
  • ~version : 명시한 version 과 근사한 버전. 자세한 내용은 semver 참조.
  • ^version : 명시한 version 과 호환되는 것. 자세한 내용은 semver 참조.
  • 1.2.x : 1.2.0, 1.2.1, 등등. 1.3.0은 제외
  • http://... : 아래의 URLs as Dependencies 항목 참조.
    • : 모든 버전
  • "" : * 와 같음
  • version1 - version2 : >= version1 <= version2 과 같음.
  • range1 || range2 : range1 또는 range2
  • git... : 하단의 Git URLs as Dependencies 항목 참조.
  • user/repo : 하단의 GitHub URLs 항목 참조.
  • tag : tag가 지정되어 publish 된 특정 버전. 자세한 내용은 npm-tag 항목 참조.
  • path/path/path : 하단의 Local Paths 항목 참조.
"dependencies": {
    "foo": "1.0.0 - 2.9999.9999",
    "bar": ">=1.0.2 <2.1.2",
    "baz": ">1.0.2 <=2.3.4",
    "boo": "2.0.1",
    "qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
    "asd": "http://asdf.com/asdf.tar.gz",
    "til": "~1.2",
    "elf": "~1.2.3",
    "two": "2.x",
    "thr": "3.3.x",
    "lat": "latest",
    "dyl": "file:../dyl"
}

URLs as Dependencies

tarball의 url을 지정할 수도 있다. 지정된 tarball은 패키지 설치시에 다운로드되고 설치된다.

Git URLs as Dependencies

다음과 같은 형태의 Git url을 지정할 수도 있다.

git://github.com/user/project.git#commit-ish git+ssh:// user @ hostname:project.git # commit-ish git+ssh://user@hostname/project.git#commit-ish git+http://user@hostname/project/blah.git#commit-ish git+https://user@hostname/project/blah.git#commit-ish

commit-ish 는 tag나 sha 또는 branch 등 git checkout 의 인자로 들어갈 수 있는 다른 값들도 가능하다. 기본값은 master 이다.

GitHub URLs

npm 버전 1.1.65 부터 GitHub url을 "foo": "user/foo-project" 와 같이 사용할 수 있다.또 commit-ish suffix 도 포함될 수 있다.

"name": "foo",
"version": "0.0.0",
"dependencies": {
    "express": "visionmedia/express",
    "mocha": "visionmedia/mocha#4727d357ea"
}

Local Paths

npm 버전 2.0.0부터 로컬 경로를 패키지에 포함시킬 수 있다. 로컬 경로는 npm install -Snpm install --save 로 설치할 수 있다.

../foo/bar ~/foo/bar ./foo/bar /foo/bar

이 경우, 아래와 같이 상대 경로를 정규화해서 package.json 에 추가하게 된다.

"name": "baz",
"dependencies": {
    "bar": "file:../foo/bar"
}

이 기능은 로컬 오프라인 개발용으로 유용하고 외부 서버에 닿지 않고 npm installing을 하는 테스트를 만들 때 유용하지만, public registry 에 올릴 때에는 절대 사용해서는 안된다.

devDependencies

패키지 모듈을 이용하는 사람이라면, 패키지 테스트 및 문서 작성에 사용되는 외부 프레임 워크는 아마도 다운로드를 원하지 않을 것이다. 이러한 경우 devDependencies 객체에 디펜던시를 추가하는 것이 좋은 방법이다.

CoffeeScript와 같이 JavaScript로 변환하는 플랫폼 특유의 전단계가 있을 때, devDependency 가 필요하다.

"name": "ethopia-waza",
"description": "a delightfully fruity coffee varietal",
"version": "1.2.3",
"devDependencies": {
    "coffee-script": "~1.6.3"
},
"scripts": {
    "prepublish": "coffee -o lib/ -c src/waza.coffee"
},
"main": "lib/waza.js"

prepublish 스크립트는 사용자들이 JavaScript로 변환하지 않고도 사용할 수 있도록 퍼블리싱을 하기전에 실행될 것이다.

peerDependencies

당신이 만든 패키지가 다른 패키지에 직접 require가 되는 것은 아니지만 그 호스트 패키지와 호환성을 가지고 있는 것을 표현하고 싶을 수 있다. 이런 것을 일반적으로 플러그인이라고 한다. 특히 당신의 모듈은 호스트 패키지의 문서에 의해 지정되거나 예측되는 특정한 인터페이스를 가지고 있을지도 모른다.

예를들면,

"name": "tea-latte",
"version": "1.3.5",
"peerDependencies": {
    "tea": "2.x"
}

위와 같은 경우 당신의 패키지인 tea-latte 는 tea 라는 호스트 패키지의 2.x 버전대와 함께 설치되는 것이 보장된다. npm install tea-latte 는 다음과 같은 의존성 그래프를 출력할 것이다.

주의할 점

npm 버전 1 과 2에서는 dependency tree에서 더높은 버전에 대한 의존성을 명시하고 있지 않으면, 자동으로 peerDependencies 를 설치했다. 하지만 다음 메이저 버전의 npm(npm@3)에서는 더이상 이 케이스에서 peerDependencies 를 설치하지 않는다. 대신 peerDependency가 설치되지 않는다는 주의 메시지를 받게 될 것이다. npm 1과 2에서의 이런 동작은 자주 오해를 일으켰고, 가능한한 npm이 피하도록 디자인한 상황인, 디펜던시 지옥을 만들었다.

요구사항이 충돌하는 서로 다른 플러그인을 설치하려고 하면 오류가 발생한다. 이런 이유로, 당신의 플러그인 요구사항은 가능한 넓어야하고 특정 패치 버전들과 묶여선 안된다.

호스트가 semver의 버전 표현 방식과 호환성을 갖는다고 하면, 호스트의 메이저 버전이 변경되는 경우에만 플러그인이 동작되지 않을 것이다. 그러므로 호스트 패키지의 모든 1.x 버전과 동작한다면, "^1.0" 또는 "1.x" 를 사용하는 것이 좋다. 만약 1.5.2 버전 이후에 소개된 기능에 의존성이 있다면, ">=1.5.2 <2" 를 사용한다.

bundledDependencies

패키지를 퍼블리싱할 때 번들되는 패키지 이름들의 목록

optionalDependencies

사용을 원하는 모듈이지만, 없거나 설치가 실패해도 npm의 패키지 설치 과정이 중단되지 않도록 하려면, optionalDependencies 를 사용한다. 여기에는 버전을 포함한 패키지 이름 혹은 url을 dependencies 와 같은 방식으로 기재한다. 차이가 있다면, 빌드가 실패해도 설치가 중단되지 않고 이어서 다른 모듈을 설치하는 것이다.

다음과 같이 의존성 모듈이 없는 경우에 대응하도록 개발했을 때 사용하는 것이 좋다.

try {
    var foo = require('foo')
    var fooVersion = require('foo/package.json').version
} catch (er) {
    foo = null
}
if ( notGoodFooVersion(fooVersion) ) {
    foo = null
}

// .. then later in your program ..

if (foo) {
    foo.doFooThings()
}

optionalDependencies 에 있는 패키지들은 dependencies 에 같은 이름이 있으면 덮어쓰게 되므로 가장 좋은 방법은 한쪽에만 기재하는 것이다.

engines

동작 가능한 node의 버전을 지정할 수 있다.

"engines" : { "node" : ">=0.10.3 <0.12" }

주의할 점은, 사용자가 engine-strict config flag 를 설정하지 않으면 이 필드는 단지 조언용으로만 사용된다.

engineStrict

이 기능은 npm 3.0.0 버전부터 deprecated 되었다. npm 3.0.0 이전에 이 기능은 사용자가 engine-strict 를 설정한 것과 같이 다루어지는 목적으로 사용되었다.

os

당신의 모듈이 어떤 운영체제에서 작동하는지 지정할 수 있다. 아래 예는 OSX와 리눅스에서 동작한다는 의미이다.

"os" : ["darwin", "linux"]

화이트리스트 방식 대신에 블랙리스트 방식으로도 지정할 수 있는데, 단순히 OS 앞에 '!' 를 붙이는 것만으로 가능하다.

"os" : ["!win32"]

운영체제의 문자열은 process.platform 에 의해서 결정된다. 블랙리스트와 화이트리스트 방식을 둘다 동시에 사용할수도 있지만, 그렇게 해야할 까닭이 별로 없을 것이다.

cpu

만약 당신의 코드가 특정한 CPU 아키텍쳐에서만 동작한다면 그것역시 명시해줄 수 있다.

"cpu" : ["x64", "ia32"]

OS 설정과 같이 블랙리스트 방식으로 지정해줄 수도 있다.

"cpu" : ["!arm", "!mips"]

호스트 아키텍쳐는 process.arch 에 의해 결정된다.

preferGlobal

패키지가 글로벌 설치(-g 옵션을 붙여 설치)를 수행해야만 한다면, 이 값을 true로 해서 local 설치시에 경고 메시지를 제공할 수 있다. 이것은 local 설치를 완전히 막지는 못하지만, 패키지가 예상과 다르게 동작하는 혼란을 피하는 데 도움이 된다.

private

만약 "private": true 로 package.json 에 설정 해두면, publish 명령을 거부하게 된다.

이 플래그는 개인적으로만 사용하는 저장소를 무심코 publish 해 버리는 것을 방지한다. 만약 (내부 레지스트리 등) 특정 레지스트리 만에 출시하는 환경을 원한다면, 아래의 publishConfig 를 이용하여 publish시 registry 설정을 덮어 쓸 수 있다.

publishConfig

publish 할때 사용되는 설정이다. tag 와 registry, access 를 다룰 때 편리한데, 이것들을 설정해서 패키지가 "lastest"로 태그되거나, public registry 에 publish 되지 않도록 또 scoped module을 기본값으로 private 로 해주는 것 등을 쉽게 설정해줄 수 있다.

설정 항목 값은 덮어쓰게 되지만, 오직 "tag"와 "registry", "access" 만 publish 의 목적에서 다뤄지게 될 것이다. 덮어 쓸 수있는 config 옵션은 npm-config 에서 확인할 수 있다.

DEFAULT VALUES

npm은 패키지 내용에 따라 몇 가지 기본값을 설정한다.

"scripts": {"start": "node server.js"}

만약 server.js 파일이 패키지의 루트에 존재하면, npm 은 기본적으로 start 커맨드를 사용했을 때, node server.js 를 실행하게 된다.

"scripts":{"preinstall": "node-gyp rebuild"}

만약 binding.gyp 파일이 패키지의 루트에 존재하면, npm 은 기본적으로 preinstall 커맨드를 사용했을 때 node-gyp 를 사용해서 컴파일한다.

"contributors": [...]

만약 AUTHORS파일이 패키지 루트에 있으면, npm은 각 라인을 name <email> (url) 포멧으로 다루게 된다. email과 url은 필수값이 아니다. # 또는 공백으로 시작되는 줄은 무시하게 된다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment