如何使用package.json文件

如何使用package.json文件

最近在整理以前寫的模塊的時候,發現不少模塊的package.json寫的並非那麼規範,因此查閱了一些資料,瞭解了一下關於如何使用package.json,列出來供你們參考javascript

本文參考了這三篇文章php

屬性列表

概述

這篇文檔告訴了你package.json裏面,包含了那些字段。這個文件必須是個json文件,而不只是一個js對象。文檔中不少屬性和設置能夠經過npm-config來生成。linux

name(必填字段)

package.json中有兩個字段是必填字段。name字段和version字段。缺乏這兩個字段則沒法安裝npm模塊。每一個npm模塊也是依賴這兩個字段做爲惟一標識。若是你的npm模塊有所修改,那麼對應的version字段也應該有所改變。git

name字段就是你的npm模塊的名稱。github

name字段須要符合如下規則:express

  • name必須<= 214 個字節,包括模塊的前綴apache

  • 不得以「_」 或者 「.」 做爲name的開頭

  • 不能有大寫字符

  • 由於name字段會成爲URL的一部分,或是命令行的一個實參,也有多是個文件夾的名字,因此不能包含no-URL-safe(URL非法)字符。

一些建議:

  • 不要用和node核心模塊同樣的名稱

  • 不要把「js」和」node」字段包含在name中。由於你實際在編寫json文件,而包含這些字段會被認爲是個js文件而非npm模塊,若是你須要指定某些引擎的話,能夠在「engines」字段中填寫。

  • name會被寫在require()的參數中,因此name最好簡短且明確。

  • 建立一個name的時候,最好去https://www.npmjs.com/查查名稱是否被佔用。

name能夠有一些前綴如 例如 @myorg/mypackage.能夠在npm-scope的中查看詳情。

version(必填字段)

package.json中有兩個字段是必填字段。name字段和version字段。缺乏這兩個字段則沒法安裝npm模塊。每一個npm模塊也是依賴這兩個字段做爲惟一標識。若是你的npm模塊有所修改,那麼對應的version字段也應該有所改變。

version字段必須能夠被node-semver這個模塊解析,是個和npm捆綁在一塊兒的包。

這裏有關於版本號形式的含義nodejs中每一個版本形式的含義

description

一段字符串,用來描述這個npm模塊的做用,經過npm search的時候回用到。

keywords

一個由字符串組成的數組,也有助於別人經過npm search的時候快速找到你的包。

homepage

這個項目的主頁URL。 注意:這裏和url屬性不是一個東西,若是你填了url屬性,npm的註冊工具會認爲你把項目發佈到別的地方了,就不會去npm官方倉庫去找。

bugs

包含你的項目的issue和email地址,若是別人在使用你的包的時候遇到了問題,能夠經過這裏找到你並提交問題。

它的格式以下:

{     
  "url" : "https://github.com/owner/project/issues",    
  "email" : "project@hostname.com"    
}

url和email你能夠選填其中一個或者兩個,若是隻填一個,能夠直接寫成字符串,而不是一個對象。

若是提供了url, 使用npm bugs命令的時候會用到。

license

給你的模塊定一個協議,讓你們知道這個模塊的使用權限。例如:遵循BSD-2-Clause or MIT協議。添加一個SPDX許可以下:

{ "license" : "BSD-3-Clause" }

這裏查看SPDX協議完整列表。理想狀況下,你應該選一個OSI許可(開源許可)。

若是你的模塊遵循多種許可,可使用SPDX協議2.0的語法,以下:

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

若是你使用的是許可證尚未分配一個SPDX標識符,或者若是您使用的是一個定製的許可證,使用這樣的字符串值:

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

而後在模塊的頂部include 這個<filename>的文件。

一些舊的模塊使用許可對象或一個「許可證」屬性,其中包含許可對象數組:

// Not valid metadata
{ "license" :
  { "type" : "ISC"
  , "url" : "http://opensource.org/licenses/ISC"
  }
}
// Not valid metadata
{ "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是一個包含一堆做者的數組。每一個person有一些描述的字段,以下:

{ "name" : "Barney Rubble"
, "email" : "b@rubble.com"
, "url" : "http://barnyrubble.tumblr.com/"
}

也能夠用下面的格式簡寫,npm會自動解析:

"Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)"

email和url屬性實際上都是能夠省略的。描述用戶信息的還有一個"maintainers"(維護者)屬性。

files

file字段是一個包含在你項目裏的文件的數組,裏面的內容是文件名或者文件夾名。若是是文件夾,那麼裏面的文件也會被包含進來,除非你設置了ignore規則。
你也能夠在模塊根目錄下建立一個".npmignore"文件(windows下沒法直接建立以"."開頭的文件,使用linux命令行工具建立如git bash),寫在這個文件裏邊的文件即使被寫在files屬性裏邊也會被排除在外,這個文件的寫法".gitignore"相似。

如下文件始終包含在內,不管是否設置:

  • package.json

  • README (and its variants)

  • CHANGELOG (and its variants)

  • LICENSE / LICENCE

相反,如下文件一般會被忽略:

  • .git

  • CVS

  • .svn

  • .hg

  • .lock-wscript

  • .wafpickle-N

  • *.swp

  • .DS_Store

  • ._*

  • npm-debug.log

main

main字段規定了程序的主入口文件。若是你的模塊命名爲foo,用戶安裝後,就會經過require("foo")來引用該模塊,返回的內容就是你的模塊的 module.exports指向的對象。

這是一個相對於你的模塊文件夾的模塊ID,對於大多數的模塊,有個主腳本就足夠了。

bin

不少模塊有一個或多個可執行文件須要配置到PATH路徑下。npm就是經過這個特性安裝,使得npm可執行。

要用這個功能,給package.json中的bin字段一個命令名到文件位置的map。初始化的時候npm會將他連接到prefix/bin(全局初始化)或者./node_modules/.bin/(本地初始化)。

例如:一個myapp模塊多是這樣:

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

因此,當你安裝myapp,npm會從cli.js文件建立一個到/usr/local/bin/myapp路徑下。

若是你只有一個可執行文件,而且名字和包名同樣。那麼你能夠只用一個字符串,好比:

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

和下面是同樣的效果:

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

man

用來給Linux下的man命令查找文檔地址,是個單一文件或者文件數組。 若是是單一文件,安裝完成後,他就是man + <pkgname>的結果,和此文件名無關,例如:

{ "name" : "foo"
, "version" : "1.2.3"
, "description" : "A packaged foo fooer for fooing foos"
, "main" : "foo.js"
, "man" : "./man/doc.1"
}

經過man foo命令會獲得 ./man/doc.1 文件的內容。
若是man文件名稱不是以模塊名稱開頭的,安裝的時候會給加上模塊名稱前綴。所以,下面這段配置:

{ "name" : "foo"
, "version" : "1.2.3"
, "description" : "A packaged foo fooer for fooing foos"
, "main" : "foo.js"
, "man" : [ "./man/foo.1", "./man/bar.1" ]

會建立一些文件來做爲man foo和man foo-bar命令的結果。
man文件必須以數字結尾,或者若是被壓縮了,以.gz結尾。數字表示文件將被安裝到man的哪一個部分。

{ "name" : "foo"
, "version" : "1.2.3"
, "description" : "A packaged foo fooer for fooing foos"
, "main" : "foo.js"
, "man" : [ "./man/foo.1", "./man/foo.2" ]
}

會建立 man foo 和 man 2 foo 兩條命令。

directories

CommonJs經過directories來制定一些方法來描述模塊的結構,看看npm的package.json文件npm's package.json ,會看到有directories標示出doc, lib, and man。

目前這個配置沒有任何做用,未來可能會整出一些花樣來。

directories.lib

告訴用戶模塊中lib目錄在哪,這個配置目前沒有任何做用,可是對使用模塊的人來講是一個頗有用的信息。

directories.bin

若是你在這裏指定了bin目錄,這個配置下面的文件會被加入到bin路徑下,若是你已經在package.json中配置了bin目錄,那麼這裏的配置將不起任何做用。

directories.man

指定一個目錄,目錄裏邊都是man文件,這是一種配置man文件的語法糖。

directories.doc

在這個目錄裏邊放一些markdown文件,可能最終有一天它們會被友好的展示出來(應該是在npm的網站上)

directories.example

放一些示例腳本,或許某一天會有用 - -!

repository

指定你的代碼存放的地方。這個對但願貢獻的人有幫助。若是git倉庫在github上,那麼npm docs命令能找到你。

以下:

"repository" :
  { "type" : "git"
  , "url" : "https://github.com/npm/npm.git"
  }
"repository" :
  { "type" : "svn"
  , "url" : "https://v8.googlecode.com/svn/trunk/"
  }

URL應該是公開的(即使是隻讀的)能直接被未通過修改的版本控制程序處理的url。不該該是一個html的項目頁面。由於它是給計算機看的。

若你的模塊放在GitHub, GitHub gist, Bitbucket, or GitLab的倉庫裏,npm install的時候可使用縮寫標記來完成:

"repository": "npm/npm"
"repository": "gist:11081aaa281"
"repository": "bitbucket:example/repo"
"repository": "gitlab:another/repo"

scripts

scripts屬性是一個對象,裏邊指定了項目的生命週期個各個環節須要執行的命令。key是生命週期中的事件,value是要執行的命令。
具體的內容有 install start stop 等,詳見npm-scripts.

config

用來設置一些項目不怎麼變化,跨版本的項目配置,例如port等。
用法以下:

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

而後有一個start命令引用npm_package_config_port環境變量,用戶也能夠用以下方式改寫:npm config set foo:port 8001

See npm-config and npm-scripts for more on package configs.

dependencies

dependencies屬性是一個對象,配置模塊依賴的模塊列表,key是模塊名稱,value是版本範圍,版本範圍是一個字符,能夠被一個或多個空格分割。

dependencies也能夠被指定爲一個git地址或者一個壓縮包地址。

不要把測試工具或transpilers寫到dependencies中。 對比下面的devDependencies。

下面是一些寫法,詳見https://docs.npmjs.com/misc/s...

  • version 精確匹配版本

  • >version 必須大於某個版本

  • >=version 大於等於

  • <version 小於

  • <=versionversion 小於

  • ~version "約等於",具體規則詳見semver文檔

  • ^version "兼容版本"具體規則詳見semver文檔

  • 1.2.x 僅一點二點幾的版本

  • http://... 見下面url做爲denpendencies的說明

  • *任何版本

  • "" 空字符,和*相同

  • version1 - version2 至關於 >=version1 <=version2.

  • range1 || range2 範圍1和範圍2知足任意一個都行

  • git... 見下面git url做爲denpendencies的說明

  • user/repo See 見下面GitHub倉庫的說明

  • tag 發佈的一個特殊的標籤,見npm-tag的文檔 https://docs.npmjs.com/gettin...

  • path/path/path 見下面本地模塊的說明

下面的寫法都是可行的:

{ "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依賴

在版本範圍的地方能夠寫一個url指向一個壓縮包,模塊安裝的時候會把這個壓縮包下載下來安裝到模塊本地。

Git URLs依賴

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,hash,或者能夠檢出的分支,默認是master分支。

github URLs

支持github的 username/modulename 的寫法,#後邊能夠加後綴寫明分支hash或標籤,以下:

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

本地路徑

npm2.0.0版本以上能夠提供一個本地路徑來安裝一個本地的模塊,經過npm install xxx --save 來安裝,格式以下:

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

package.json 生成的相對路徑以下:

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

這種屬性在離線開發或者測試須要用npm install的狀況,又不想本身搞一個npm server的時候有用,可是發佈模塊到公共倉庫時不該該使用這種屬性。

devDependencies

若是別人只想使用你的模塊,而不須要開發和測試所須要的依賴的時候,這種狀況下,能夠將開發測試依賴的包,寫到devDependencies中。

這些模塊會在npm link或者npm install的時候被安裝,也能夠像其餘npm配置同樣被管理,詳見npm的config文檔。
對於一些跨平臺的構建任務,例如把CoffeeScript編譯成JavaScript,就能夠經過在package.json的script屬性裏邊配置prepublish腳原本完成這個任務,而後須要依賴的coffee-script模塊就寫在devDependencies屬性種。
例如:

{ "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腳本會在publishing前運行,這樣用戶就不用本身去require來編譯就能使用。而且在開發模式中(好比本地運行npm install)會運行這個腳本以便更好地測試。

peerDependencies

有時,你的項目和所依賴的模塊,都會同時依賴另外一個模塊,可是所依賴的版本不同。好比,你的項目依賴A模塊和B模塊的1.0版,而A模塊自己又依賴B模塊的2.0版。

大多數狀況下,這不構成問題,B模塊的兩個版本能夠並存,同時運行。可是,有一種狀況,會出現問題,就是這種依賴關係將暴露給用戶。

最典型的場景就是插件,好比A模塊是B模塊的插件。用戶安裝的B模塊是1.0版本,可是A插件只能和2.0版本的B模塊一塊兒使用。這時,用戶要是將1.0版本的B的實例傳給A,就會出現問題。所以,須要一種機制,在模板安裝的時候提醒用戶,若是A和B一塊兒安裝,那麼B必須是2.0模塊。

peerDependencies字段,就是用來供插件指定其所須要的主工具的版本。

例如:

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

上面這個配置確保再npm install的時候tea-latte會和2.x版本的tea一塊兒安裝,並且它們兩個的依賴關係是同級的:

├── tea-latte@1.3.5
└── tea@2.2.0

這個配置的目的是讓npm知道,若是要使用此插件模塊,請確保安裝了兼容版本的宿主模塊。

bundledDependencies

指定發佈的時候會被一塊兒打包的模塊。

optionalDependencies

若是一個依賴模塊能夠被使用, 但你也但願在該模塊找不到或沒法獲取時npm不中斷運行,你能夠把這個模塊依賴放到optionalDependencies配置中。這個配置的寫法和dependencies的寫法同樣,不一樣的是這裏邊寫的模塊安裝失敗不會致使npm install失敗。
可是須要本身處理模塊缺失的狀況,例如:

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" } }

和dependencies同樣,若是你不指定版本範圍或者指定爲*,任何版本的node均可以。
也能夠指定一些npm版本能夠正確的安裝你的模塊,例如:

{ "engines" : { "npm" : "~1.0.20" } }

記住,除非用戶設置engine-strict標記,F不然這個字段只是建議值。

engineStrict

注意:這個屬性已經棄用,將在npm 3.0.0 版本幹掉。

os

指定你的模塊只能在哪一個操做系統上跑:

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

也能夠指定黑名單而不是白名單:

"os" : [ "!win32" ]

操做系統是由process.platform來判斷的,這個屬性容許黑白名單同時存在,雖然沒啥必要.

cpu

若是你的代碼只能運行在特定的cpu架構下,你能夠指定一個:

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

也能夠設置黑名單:

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

cpu架構經過 process.arch 判斷

preferGlobal

若是你的模塊主要是須要全局安裝的命令行程序,就設置它爲true,就會提供一個warning,這樣來只在局部安裝的人會獲得這個warning。

它不會真正的防止用戶在局部安裝,只是防止該模塊被錯誤的使用引發一些問題。

private

若是這個屬性被設置爲true,npm將不會發布它。

這是爲了防止一個私有模塊被無心間發佈出去。若是你想讓模塊被髮布到一個特定的npm倉庫,如一個內部的倉庫,可與在下面的publishConfig中配置倉庫參數。

publishConfig

這是一個在publish-time時會用到的配置集合。當你想設置tag、registry或access時特別有用,因此你能夠確保一個給定的包沒法在沒有被打上"latest"標記時就被髮布到全局公共的registry。

任何配置均可以被覆蓋,固然可能只有"tag", "registry"和"access"和發佈意圖有關。

參考npm-config來查看那些能夠被覆蓋的配置項列表。

DEFAULT VALUES

npm會根據包的內容設置一些默認值。

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

若是模塊根目錄下有一個server.js文件,那麼npm start會默認運行這個文件。

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

若是模塊根目錄下有binding.gyp, npm將默認用node-gyp來編譯preinstall的腳本

"contributors": [...]

若模塊根目錄下有AUTHORS 文件,則npm會按Name (url)格式解析每一行的數據添加到contributors中,能夠用#添加行註釋

參考資料

相關文章
相關標籤/搜索