如何使用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中,能够用#添加行注释

参考资料

相关文章
相关标签/搜索