最近在整理以前寫的模塊的時候,發現不少模塊的package.json寫的並非那麼規範,因此查閱了一些資料,瞭解了一下關於如何使用package.json,列出來供你們參考javascript
本文參考了這三篇文章php
這篇文檔告訴了你package.json裏面,包含了那些字段。這個文件必須是個json文件,而不只是一個js對象。文檔中不少屬性和設置能夠經過npm-config來生成。linux
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的中查看詳情。
package.json中有兩個字段是必填字段。name字段和version字段。缺乏這兩個字段則沒法安裝npm模塊。每一個npm模塊也是依賴這兩個字段做爲惟一標識。若是你的npm模塊有所修改,那麼對應的version字段也應該有所改變。
version字段必須能夠被node-semver這個模塊解析,是個和npm捆綁在一塊兒的包。
這裏有關於版本號形式的含義nodejs中每一個版本形式的含義
一段字符串,用來描述這個npm模塊的做用,經過npm search的時候回用到。
一個由字符串組成的數組,也有助於別人經過npm search的時候快速找到你的包。
這個項目的主頁URL。 注意:這裏和url屬性不是一個東西,若是你填了url屬性,npm的註冊工具會認爲你把項目發佈到別的地方了,就不會去npm官方倉庫去找。
包含你的項目的issue和email地址,若是別人在使用你的包的時候遇到了問題,能夠經過這裏找到你並提交問題。
它的格式以下:
{ "url" : "https://github.com/owner/project/issues", "email" : "project@hostname.com" }
url和email你能夠選填其中一個或者兩個,若是隻填一個,能夠直接寫成字符串,而不是一個對象。
若是提供了url, 使用npm bugs命令的時候會用到。
給你的模塊定一個協議,讓你們知道這個模塊的使用權限。例如:遵循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,來防止模塊的意外發布
用戶相關的屬性: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"(維護者)屬性。
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字段規定了程序的主入口文件。若是你的模塊命名爲foo,用戶安裝後,就會經過require("foo")來引用該模塊,返回的內容就是你的模塊的 module.exports指向的對象。
這是一個相對於你的模塊文件夾的模塊ID,對於大多數的模塊,有個主腳本就足夠了。
不少模塊有一個或多個可執行文件須要配置到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" } }
用來給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 兩條命令。
CommonJs經過directories來制定一些方法來描述模塊的結構,看看npm的package.json文件npm's package.json ,會看到有directories標示出doc, lib, and man。
目前這個配置沒有任何做用,未來可能會整出一些花樣來。
告訴用戶模塊中lib目錄在哪,這個配置目前沒有任何做用,可是對使用模塊的人來講是一個頗有用的信息。
若是你在這裏指定了bin目錄,這個配置下面的文件會被加入到bin路徑下,若是你已經在package.json中配置了bin目錄,那麼這裏的配置將不起任何做用。
指定一個目錄,目錄裏邊都是man文件,這是一種配置man文件的語法糖。
在這個目錄裏邊放一些markdown文件,可能最終有一天它們會被友好的展示出來(應該是在npm的網站上)
放一些示例腳本,或許某一天會有用 - -!
指定你的代碼存放的地方。這個對但願貢獻的人有幫助。若是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屬性是一個對象,裏邊指定了項目的生命週期個各個環節須要執行的命令。key是生命週期中的事件,value是要執行的命令。
具體的內容有 install start stop 等,詳見npm-scripts.
用來設置一些項目不怎麼變化,跨版本的項目配置,例如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屬性是一個對象,配置模塊依賴的模塊列表,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" } }
在版本範圍的地方能夠寫一個url指向一個壓縮包,模塊安裝的時候會把這個壓縮包下載下來安裝到模塊本地。
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的 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中。
這些模塊會在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)會運行這個腳本以便更好地測試。
有時,你的項目和所依賴的模塊,都會同時依賴另外一個模塊,可是所依賴的版本不同。好比,你的項目依賴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知道,若是要使用此插件模塊,請確保安裝了兼容版本的宿主模塊。
指定發佈的時候會被一塊兒打包的模塊。
若是一個依賴模塊能夠被使用, 但你也但願在該模塊找不到或沒法獲取時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中同名的配置,最好只在一個地方寫。
你能夠指定項目的node的版本:
{ "engines" : { "node" : ">=0.10.3 <0.12" } }
和dependencies同樣,若是你不指定版本範圍或者指定爲*,任何版本的node均可以。
也能夠指定一些npm版本能夠正確的安裝你的模塊,例如:
{ "engines" : { "npm" : "~1.0.20" } }
記住,除非用戶設置engine-strict標記,F不然這個字段只是建議值。
注意:這個屬性已經棄用,將在npm 3.0.0 版本幹掉。
指定你的模塊只能在哪一個操做系統上跑:
"os" : [ "darwin", "linux" ]
也能夠指定黑名單而不是白名單:
"os" : [ "!win32" ]
操做系統是由process.platform來判斷的,這個屬性容許黑白名單同時存在,雖然沒啥必要.
若是你的代碼只能運行在特定的cpu架構下,你能夠指定一個:
"cpu" : [ "x64", "ia32" ]
也能夠設置黑名單:
"cpu" : [ "!arm", "!mips" ]
cpu架構經過 process.arch 判斷
若是你的模塊主要是須要全局安裝的命令行程序,就設置它爲true,就會提供一個warning,這樣來只在局部安裝的人會獲得這個warning。
它不會真正的防止用戶在局部安裝,只是防止該模塊被錯誤的使用引發一些問題。
若是這個屬性被設置爲true,npm將不會發布它。
這是爲了防止一個私有模塊被無心間發佈出去。若是你想讓模塊被髮布到一個特定的npm倉庫,如一個內部的倉庫,可與在下面的publishConfig中配置倉庫參數。
這是一個在publish-time時會用到的配置集合。當你想設置tag、registry或access時特別有用,因此你能夠確保一個給定的包沒法在沒有被打上"latest"標記時就被髮布到全局公共的registry。
任何配置均可以被覆蓋,固然可能只有"tag", "registry"和"access"和發佈意圖有關。
參考npm-config來查看那些能夠被覆蓋的配置項列表。
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中,能夠用#添加行註釋
參考資料