package.json不完全说明

918 阅读6分钟

前言

之所以写下这篇文,是因为前两天忽然发现,package.json里的版本号我好像就没注意过了,一会~开头,一会^开头,都是个啥?然后仔细回想了下发现我好像并没有真的了解过这玩意,每次打开个项目都是npm install一波敲敲启动命令就完事了。事后深刻反思了下觉得这样并不好万一某天来个人问你这里的XX是啥意思你都说不上来那多尴尬,于是就有了这篇文。

正文

1. npm

在介绍package.json前,需要先介绍一下npm。npm就是一个包含了很多Javascript包(package)的公有仓库(registry),开源开发者们可以贡献包,也可以在自己的项目中下载包。

有关package和modules的描述可以查看官方文档(这波懒得翻译了

About packages and modules

2. package.json

package.json是用来管理包的。要将一个包发布到npm中,必须要包含一个package.json文件。

package.json文件的作用:

  • 列举出你的项目所依赖的包;
  • 明确你的项目中可以使用的包的版本;
  • 让你的包能够进行二次开发,更加容易和其他开发者分享;

创建package.json

创建方式有两种,通过命令行创建或者直接创建默认的package.json文件。

命令行: 进入项目目录-> npm init,然后通过命令行交互进行创建即可。

自定义创建package.json的命令行交互:可参考init-package-json

创建默认文件:可以使用当前目录内抽取的信息直接生成默认的package.json文件。进入项目目录-> npm init --yes | npm init -y

我们也可以配置初始化命令的配置项来设置默认值:

> npm set init.author.email "example-user@example.com"
> npm set init.author.name "example_user"
> npm set init.license "MIT"

3. 配置项

name

如果你要发布你的包,那么配置nameversion字段是必须要填写且十分重要的;如果并不需要发布,那么name和version是可选的。

对于name和version字段有一些限制:

  • name不能大于214个字符。如果是作用域包,也包含它的作用域。
  • 作用域包的name可以以.或者_开头。非作用域包的话是不允许的。
  • 新包的name中不能包含大写字母
  • name最终会成为URL/命令行中的参数/文件名的一部分,因此name中不能包含非URL安全的字符

version

对于要发布的包来说,version和name一样重要。version必须能够被node-semver解析。

description

description能够帮助人们使用npm search搜索到你的包。

keywords

keywords是一个字符串数组。和description一样能够帮助人们使用npm search搜索到你的包。

homepage

链接到项目主页的url。

"homepage": "https://github.com/owner/project#readme"

bugs

链接到项目issue的url or 提issue的邮箱地址。

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

两个值都是可选的,如果你只想用一个url,直接指定bugs的值为url字符串即可,不需要对象。

license

包应该指定一个license,这样其他用户就能够知道你的包可以如何使用,有哪些限制。

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

在一些旧的包中license是使用对象or对象数组声明的,现在已经不推荐使用了。

author, contributors

作者和贡献者们。可以用一个包含name字段的对象描述,url和email可选。

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

或者可以简写到一个字符串中,npm会自动解析:

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

main

main字段指定了项目的入口。

browser

如果你的模块是用在客户端上的,那么应该指定browser字段而不是main字段。

bin

bin字段包含了一组命令到本地文件名的映射。安装包的时候,对于全局安装npm会创建一个文件到prefix/bin的符号链接,而对于局部安装,npm会创建文件到./node_modules/.bin/的符号链接。

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

当我们安装myapp的时候,它就会创建一个从cli.js/usr/local/bin/myapp的符号链接。

如果你的包中只有一条可执行命令并且命令名称和报名相同,那么就可以直接用字符串来声明:

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

repository

指定了代码仓库的位置。

scripts

scripts属性是一个字典,其中包含了在包生命周期的不同时间运行的脚本命令。键是生命周期事件,值是在该点运行的命令。详见Scripts

dependencies

dependencies是一个对象,对象中包含了包名到版本范围的映射。版本范围是一个具有一个或多个空格分隔的描述字符串,dependencies也可以用tarballgit URL标识。

注意:请不要将测试、编译或者其他在开发阶段使用的工具放在dependencies中。

版本范围说明:详见node-semver:README Versions部分。

相关阅读:语义化版本号

摘取一部分常见版本范围说明:

操作符 意义 说明
< 小于 <1.2.7将匹配版本1.2.6、1.0.1、0.0.2,但不匹配版本1.2.7、2.0.0等
<= 小于等于 <=1.2.7将匹配版本1.2.7、1.2.6,但不匹配版本1.2.8、2.0.0等
> 大于 >1.2.7将匹配版本1.2.8、2.0.0,但不匹配版本1.2.7、1.0.0等
>= 大于等于 >=1.2.7将匹配版本1.2.7、2.0.0,但不匹配版本1.2.6、1.0.0等
~ 匹配次要版本 ~1.2.3:= >=1.2.3 <1.(2+1).0:= >=1.2.3 <1.3.0-0
~1.2:= >=1.2.0 <1.(2+1).0:= >=1.2.0 <1.3.0-0
~1:= >=1.0.0 <(1+1).0.0:= >=1.0.0 <2.0.0-0
^ 匹配兼容版本 ^2.3.1:与2.3.1版本兼容即>=2.3.1 < 3.0.0,不改变大版本号

devDependencies

和测试、编译或者其他在开发阶段使用的相关工具应该放在devDependencies中。

peerDependencies

在某些开发场景下,你的包需要某些依赖的支持,但是没必要去安装,因为包的宿主会去安装这些依赖,这时就可以用peerDependencies去声明一下需要依赖的包和版本,如果出问题npm就会有警告来提醒使用者去解决版本冲突问题。

engines

可以通过engines来指定包运行node版本,或者指定哪些版本的npm可以正确运行你的程序:

{
  "engines": {
    "node": ">=0.10.3 <15",
    "npm": "~1.0.20"
  }
}

os

可以用来指定你的程序运行的操作系统:

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

也可以用非操作符来禁止在某个操作系统上运行:

{
  "os": [
    "!win32"
  ]
}

cpu

可以用来指定你的程序运行的cpu:

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

同样可以用非操作符来禁止在某个cpu上运行,同上。

private

如果设置了private: true,那么npm就不会发布你的包。这是一种防止意外发布私有库的方法。如果要确保给定的包只发布到特定的库中,那么可以使用publishConfig发布时重写配置参数。

publishConfig

这是一组用来发布时使用的配置值。详细配置请看config

总结

遇到不懂的还是要多看多总结,官方文档是个好东西不要因为全是英文的就不看啊

相关链接

  1. package.json
  2. About packages and modules
  3. init-package-json
  4. Scripts
  5. node-semver:README
  6. 语义化版本号
  7. config