(译)package.json详解

概述

本文囊括了所有package.json文件中你需要知道的细节。注意package.json必须是纯JSON的,而不仅仅是一个JavaScript对象字面量。 
该文件描述的很多行为都受npm-config中的配置影响。

下面分别介绍package.json中各个字段的含义和用法。

name

name和version字段是package.json文件中最重要的字段。这是必须的字段,如果你的npm包没有指定这两个字段,将无法被安装。name和version字段被假定组合成一个唯一的标识符。包内容的更改和包版本的更改是同步的。

name字段的含义不需要过多解释,就是npm包名。

几个规则:

  1. name的长度必须小于等于214个字符。
  2. name不能以”.”(点)或者”_”(下划线)开头。
  3. name中不能包含大写字母。
  4. name最终将被用作URL的一部分、命令行的参数和文件夹名。因此,name不能含有非URL安全的字符。

几个建议:

  1. 不要使用已存在的name作为包名。
  2. 不要在name中使用”js”和”node”,这会假定这是js文件,一旦你写一个package.json文件,你就可以在”engines”字段中指定解释器引擎。
  3. name字段可能会被作为传输传递给require()函数,因此它最好是简短的、自描述的。
  4. 你可能会需要在深入开发一个包之前先检查npm的registry来确认某个name是否被使用过,可以参考https://www.npmjs.com/

一个name可以用scope来指定一个前缀,比如@myorg/mypackage,可以参考npm-scope

version

name和version字段是package.json文件中最重要的字段。这是必须的字段,如果你的npm包没有指定这两个字段,将无法被安装。name和version字段被假定组合成一个唯一的标识符。包内容的更改和包版本的更改是同步的。

version字段必须能够被node-semver解析,node-semver作为依赖项被捆绑进了npm中。(可以使用npm install semver来使用)

关于版本号和范围的信息可以参考semver

description

npm包的描述,description是一个字符串。它可以帮助人们在使用npm search时找到这个包。

keywords

npm包的关键字,keywords是一个字符串的数组。它可以帮助人们在使用npm search时找到这个包。

homepage

项目主页的url。

注意: 这和”url”不一样。如果你放一个”url”字段,registry会以为是一个跳转到你发布在其他地方的地址,然后鄙视你。

bugs

改项目的issue跟踪页面或这报告issue的email地址。这对使用这个包遇到问题的用户会有帮助。

差不多是这样:

{ 
  "url" : "https://github.com/owner/project/issues",
  "email" : "project@hostname.com"
}
  • 1
  • 2
  • 3
  • 4

你可以择其一或者两个都写上。如果只想提供一个url,你可以对”bugs”字段指定一个字符串而不是object。

如果提供了一个url,它会被用于npm bugs命令。

license

你应该对你的包指定一个license来让用户知道他们的使用权利和和任何限制。

如果你正在使用BSD-2-Clause或MIT这样的通用许可证,可以为你的license添加一个当前SPDX的许可证标识符,比如:

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

你可以查看SPDX许可证标识符的完整列表,理想情况下你应该挑选一个经过OSI核准的标识符。

如果你的包在多个通用许可证下被授权,使用一个SPDX许可证表达式语法v2.0,比如:

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

如果你正在使用的许可未被授予一个SPDX标识符,或者你正在使用自定义的许可证,使用如下:

{ "license" : "SEE LICENSE IN " }

然后在包的根目录下提供一个叫的许可证文件。

一些旧的包使用license对象或一个”license”属性包含一个license的数组:

// Not valid metadata
{ "license" :
    { 
        "type" : "ISC",
        "url" : "http://opensource.org/licenses/ISC"
    }
}        
//Notvalidmetadata
{
    "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

author是一个人,contributors是一些人的数组。person是一个对象,拥有必须的name字段和可选的url和email字段,像这样:

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

或者你也可以使用单个字符串的精简形式,npm会帮你解析它:

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

这里email和url也是可选的。

npm也会使用你提供的npm用户信息来设置一个顶级的”maintainers”字段。

files

files字段是一个被项目包含的文件名数组,如果你在里面放一个文件夹名,那么这个文件夹中的所有文件都会被包含进项目中(除非是那些在其他规则中被忽略的文件)。

你还可以在包的根目录或子目录下提供一个”.npmignore”文件来忽略项目包含文件,即使这些文件被包含在files字段中。.npmignore文件和.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”),则这个main字段指定的模块的导出对象会被返回。

这应该是一个相对于包根目录的模块标识。

对于大部分模块来说,main字段除了指定一个主入口文件以外没什么其他用处了。

bin

许多包有一个或多个可执行文件希望被安装到系统路径。在npm下要这么做非常容易(事实上,npm就是这么运行的)。

这需要在你的package.json中提供一个bin字段,它是一个命令名和本地文件名的映射。在安装时,如果是全局安装,npm将会使用符号链接把这些文件链接到prefix/bin,如果是本地安装,会链接到./node_modules/.bin/。

比如,要使用myapp作为命令时可以这么做:

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

这么一来,当你安装myapp,npm会从cli.js文件创建一个到/usr/local/bin/myapp的符号链接(这使你可以直接在命令行执行myapp)。

如果你只有一个可执行文件,那么它的名字应该和包名相同,此时只需要提供这个文件路径(字符串),比如:

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

这和以下这种写法相同:

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

man

指定一个单一的文件名或一个文件名数组来让man程序使用。

如果只给man字段提供一个文件,则安装完毕后,它就是man 的结果,这和此文件名无关,比如:

{
    "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这个文件。

如果指定的文件名并未以包名开头,那么它会被冠以前缀,像这样:

{
    "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后缀(当它被压缩时)。这个数字说明了这个文件被安装到哪个节中。

{
    "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 Packages规范说明了几种你可以用directories对象来标示你的包结构的方法。如果你去看npm’s package.json,你会看到它标示出出doc、lib和man。

在未来,这个信息可能会被用到。

directories.lib

告诉你库文件夹的位置,目前没有什么地方需要用到lib文件夹,但是这是重要的元信息。

directories.bin

如果你在directories.bin中指定一个bin目录,在这个目录中的所有文件都会被当做在bin来使用。

由于bin指令的工作方式,同时指定一个bin路径和设置directories.bin将是一个错误。如果你想指定独立的文件,使用bin,如果想执行某个文件夹里的所有文件,使用directories.bin。

directories.man

directories.man指定的文件夹里都是man文件,系统通过遍历这个文件夹来生成一个man的数组。

directories.doc

把markdown文件放在这。也许某一天这些文件将被漂亮地展示出来,不过这仅仅是也许。

directories.example

把示例脚本放在这。也许某一天会被用到。

repository

指明你的代码被托管在何处,这对那些想要参与到这个项目中的人来说很有帮助。如果git仓库在github上,用npm docs命令将会找到你。

像这样:

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

url应该是公开且可用的(可能是只读的),这个url应该可以被版本控制系统不经修改地处理。不应该是一个在浏览器中打开的html项目页面,这个url是给计算机使用的。

对于github、github gist、Bitbucket或GitLab的仓库,你可以在npm install中使用相同的缩写形式:

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

scripts

scripts字段是一个由脚本命令组成的字典,这些命令运行在包的各个生命周期中。这里的键是生命周期事件名,值是要运行的命令。可以参考npm-scripts获取配置scripts的更多信息。

config

config字段是一个对象,可以用来配置包脚本中的跨版本参数,比如如下这个实例:

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

然后有一个start命令引用npm_package_config_port环境变量,用户也可以用如下方式改写:

npm config set foo:port 8001

可以参考npm-confignpm-scripts获得更多关于包配置的信息。

dependencies

dependencies字段是一个对象,它指定了依赖的包名和其版本范围的映射。版本范围是个有一个或多个空白分隔描述符的字符串。dependencies字段还可以用tarball或者git URL。

请不要将测试或过渡性的依赖放到dependencies中,请参考下面的devDependencies。

可以参考semver获取更多关于指定版本范围的细节信息。

1. version 必须确切匹配这个version 
2. >version 必须大于这个version 
3. >=version 必须大于等于这个version 
4. < version 必须小于这个version 
5. <=version 必须小于等于这个version 
6. ~version 大约相当于version,参考semver 
7. ^version 与version兼容,参考semver 
8. 1.2.x 可以是1.2.0、1.2.1等,但不能是1.3.0 
9. http://… 参考下面的URL作为依赖项 
10. * 匹配任何版本 
11. “”(空字符串) 匹配任何版本,和*一样 
12. version1 - version2 相当于 >=version1 <=version2 
13. range1 || range2 range1或range2其中一个满足时采用该version 
14. git… 参考下面的Git URL作为依赖项 
15. user/repo 参考下面的GitHub URLs 
16. tag 一个以tag发布的指定版本,参考npm-tag 
17. path/path/path 参考下面的本地Paths

举个栗子,下面这种写法是合法的:

{
    "dependencies": {
        "foo": "1.0.0 - 2.9999.9999",
        "bar": ">=1.0.2 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值