package.json指南

在日常开发工作中,相信大家对于 package.json 并不陌生,但对于 package.json的各属性的含义,是否都详细了解呢?如果对于它了如指掌了,那么可忽略本文。对于尚不太熟悉的人,请继续阅读。

对于应用程序,package.json 文件中的内容没有固定的要求。 唯一的要求是必须遵守 JSON 格式,否则,尝试以编程的方式访问其属性的程序则无法读取它。

它必须是实际的JSON,而不仅仅是JavaScript对象文字。

实例

选取了一个典型的package.json实例,vue仓库的package.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
{
"name": "vue",
"version": "2.6.12",
"description": "Reactive, component-oriented view layer for modern web interfaces.",
"main": "dist/vue.runtime.common.js",
"module": "dist/vue.runtime.esm.js",
"unpkg": "dist/vue.js",
"jsdelivr": "dist/vue.js",
"typings": "types/index.d.ts",
"files": [
"src",
"dist/*.js",
"types/*.d.ts"
],
"sideEffects": false,
"scripts": {
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
"dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",
"dev:esm": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-esm",
"dev:test": "karma start test/unit/karma.dev.config.js",
"dev:ssr": "rollup -w -c scripts/config.js --environment TARGET:web-server-renderer",
"dev:compiler": "rollup -w -c scripts/config.js --environment TARGET:web-compiler ",
"dev:weex": "rollup -w -c scripts/config.js --environment TARGET:weex-framework",
"dev:weex:factory": "rollup -w -c scripts/config.js --environment TARGET:weex-factory",
"dev:weex:compiler": "rollup -w -c scripts/config.js --environment TARGET:weex-compiler ",
"build": "node scripts/build.js",
"build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
"build:weex": "npm run build -- weex",
"test": "npm run lint && flow check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr && npm run test:weex",
"test:unit": "karma start test/unit/karma.unit.config.js",
"test:cover": "karma start test/unit/karma.cover.config.js",
"test:e2e": "npm run build -- web-full-prod,web-server-basic-renderer && node test/e2e/runner.js",
"test:weex": "npm run build:weex && jasmine JASMINE_CONFIG_PATH=test/weex/jasmine.js",
"test:ssr": "npm run build:ssr && jasmine JASMINE_CONFIG_PATH=test/ssr/jasmine.js",
"test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2",
"test:types": "tsc -p ./types/test/tsconfig.json",
"lint": "eslint src scripts test",
"flow": "flow check",
"sauce": "karma start test/unit/karma.sauce.config.js",
"bench:ssr": "npm run build:ssr && node benchmarks/ssr/renderToString.js && node benchmarks/ssr/renderToStream.js",
"release": "bash scripts/release.sh",
"release:weex": "bash scripts/release-weex.sh",
"release:note": "node scripts/gen-release-note.js",
"commit": "git-cz"
},
"gitHooks": {
"pre-commit": "lint-staged",
"commit-msg": "node scripts/verify-commit-msg.js"
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vue.git"
},
"keywords": [
"vue"
],
"author": "Evan You",
"license": "MIT",
"bugs": {
"url": "https://github.com/vuejs/vue/issues"
},
"homepage": "https://github.com/vuejs/vue#readme",
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.0.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/register": "^7.0.0",
"@types/node": "^12.12.0",
"@types/webpack": "^4.4.22",
"acorn": "^5.2.1",
"babel-eslint": "^10.0.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^8.0.4",
"babel-plugin-istanbul": "^5.1.0",
"babel-plugin-transform-vue-jsx": "^4.0.1",
"babel-preset-flow-vue": "^1.0.0",
"buble": "^0.19.3",
"chalk": "^2.3.0",
"chromedriver": "^2.45.0",
"codecov": "^3.0.0",
"commitizen": "^2.9.6",
"conventional-changelog": "^1.1.3",
"cross-spawn": "^6.0.5",
"cz-conventional-changelog": "^2.0.0",
"de-indent": "^1.0.2",
"es6-promise": "^4.1.0",
"escodegen": "^1.8.1",
"eslint": "^5.7.0",
"eslint-plugin-flowtype": "^2.34.0",
"eslint-plugin-jasmine": "^2.8.4",
"file-loader": "^3.0.1",
"flow-bin": "^0.61.0",
"hash-sum": "^1.0.2",
"he": "^1.1.1",
"http-server": "^0.11.1",
"jasmine": "^2.99.0",
"jasmine-core": "^2.99.0",
"karma": "^3.1.1",
"karma-chrome-launcher": "^2.1.1",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.0.1",
"karma-jasmine": "^1.1.0",
"karma-mocha-reporter": "^2.2.3",
"karma-phantomjs-launcher": "^1.0.4",
"karma-safari-launcher": "^1.0.0",
"karma-sauce-launcher": "^2.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^4.0.0-rc.2",
"lint-staged": "^8.0.0",
"lodash": "^4.17.4",
"lodash.template": "^4.4.0",
"lodash.uniq": "^4.5.0",
"lru-cache": "^5.1.1",
"nightwatch": "^0.9.16",
"nightwatch-helpers": "^1.2.0",
"phantomjs-prebuilt": "^2.1.14",
"puppeteer": "^1.11.0",
"resolve": "^1.3.3",
"rollup": "^1.0.0",
"rollup-plugin-alias": "^1.3.1",
"rollup-plugin-buble": "^0.19.6",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-flow-no-whitespace": "^1.0.0",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-replace": "^2.0.0",
"selenium-server": "^2.53.1",
"serialize-javascript": "^3.1.0",
"shelljs": "^0.8.1",
"terser": "^3.10.2",
"typescript": "^3.6.4",
"webpack": "~4.28.4",
"weex-js-runtime": "^0.23.6",
"weex-styler": "^0.3.0",
"yorkie": "^2.0.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}

主要属性简介

name ✨

设置 npm包或者工程项目的名称。

一些规则:

  • 名称必须少于214个字符,且不能包含空格,只能包含小写字母、连字符(-)或下划线(_)。
  • 新包的名称不能有大写字母
  • 名称最终成为URL的一部分、命令行上的参数和文件夹名称。因此,名称不能包含任何非url安全字符。

一些tips:

  • 不要使用与 Node 核心模块相同的名称
  • 不要在名称中加入 js 或 node。
  • 名称可能作为参数传递给 require(), 因此它应该简短,但也具有合理的描述性。
1
2
3
{
"name": "vue"
}

author

npm包或者工程项目的作者

contributors

除作者外,该项目可以有一个或多个贡献者。此属性为数组结构。

version ✨

指定 npm包或者工程项目的当前版本。

该属性遵循版本的语义版本控制记法,意味着该版本始终以3个数字表示: x.x.x

Version 必须能够被 node-semver 解析。具体规范参考semver

1
2
3
{
"version": "2.6.12"
}

description ✨

对 npm包或者工程项目的简短描述。

它将被展示在 npm search, 这有助于开发者发现你的 package。

1
2
3
{
"description": "Reactive, component-oriented view layer for modern web interfaces."
}

keywords ✨

设置关键字,它是一个字符串数组。

它将被列出在 npm search,这有助于开发者发现你的 package。

1
2
3
4
5
{
"keywords": [
"vue"
]
}

homepage

设置 npm包或者工程项目的主页,通常指向项目的readme。

1
2
3
{
"homepage": "https://github.com/vuejs/vue#readme"
}

bugs

项目的问题跟踪的 url 或应该报告问题的电子邮件地址。

这些对遇到您的软件包问题的人很有帮助。最常见的和上面的 vue 的类似,指向项目的 issues。

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

licence ✨

指定软件的许可证。

1
2
3
{
"licence": "MIT"
}

最流行的六开源许可证: GPL、BSD、MIT、Mozilla、Apache和 LGPL。

具体区分参考如何选择开源许可证?

funding

可以指定一个对象,其中包含一个URL,该URL提供有关帮助您的 package 开发的资金的最新信息(比较少看到😂),可以是一个字符串URL,也可以为数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"funding": {
"type" : "individual",
"url" : "http://example.com/donate"
}

"funding": {
"type" : "patreon",
"url" : "https://www.patreon.com/my-account"
}

"funding": "http://example.com/donate"

"funding": [
{
"type" : "individual",
"url" : "http://example.com/donate"
},
"http://example.com/donateAlso",
{
"type" : "patreon",
"url" : "https://www.patreon.com/my-account"
}
]

files

可选的 files 字段为一个文件模式数组,描述当你的 package 作为依赖被安装时要包含的选项。

1
2
3
4
5
"files": [
"src",
"dist/*.js",
"types/*.d.ts"
]

文件模式遵循与 .gitignore相近的语法,但是表达的意义想法,它是指包含一个文件、目录或者 glob模式。

省略该字段,将使其默认为 [“*”],意味着它将包含所有文件。

您还可以在包的根目录或子目录中提供.npmignore文件,它将防止包含文件。在包的根目录下,它不会覆盖“files”字段,但在子目录中会覆盖。npmignore文件就像.gitignore一样工作。如果有一个.gitignore文件,并且丢失了.npmignore,那么.gitignore的内容将被使用。

包含在 “package.json#file” 中的文件,不能通过.npmignore或.gitignore排除。

main

设置 package 的入口。

当在应用程序中导入此 package 时,应用程序会在该位置搜索模块的导出。

1
2
3
{
"main": "dist/vue.runtime.common.js"
}

browserslist

如果你的 package 用于浏览器端,该字段用于说明,你的 package 支持的浏览器及其版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"browserslist": [
"Android >= 7",
"IOS >= 11",
"Safari >= 11",
"Chrome >= 49",
"Firefox >= 31",
"Samsung >= 5"
]
}

// 以下配置说明需要支持使用率超过 %1的所有浏览器的最新的两个主版本,但不包含 IE8 及更低版本。
{
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

scripts ✨

scripts 指定了运行脚本命令的 npm 命令行的缩写。

1
2
3
4
5
6
7
8
9
{
"scripts": {
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
"dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",
"dev:esm": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-esm",
"dev:test": "karma start test/unit/karma.dev.config.js",
"dev:ssr": "rollup -w -c scripts/config.js --environment TARGET:web-server-renderer"
}
}

bin

bin项用来指定各个内部命令对应的可执行文件的位置。

1
2
3
4
5
{
"bin": {
"someTool": "./bin/someTool.js"
}
}

上面代码指定,someTool 命令对应的可执行文件为 bin 子目录下的 someTool.js。Npm会寻找这个文件,在node_modules/.bin/目录下建立符号链接。在上面的例子中,someTool.js会建立符号链接node_modules/.bin/someTool。由于node_modules/.bin/目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用这些脚本。

因此,像下面这样的写法可以采用简写。

1
2
3
4
5
6
7
8
9
10
11
{
"scripts": {
"start": "./node_modules/bin/someTool.js build"
}
}
// 简写为
{
"scripts": {
"start": "someTool build"
}
}

所有node_modules/.bin/目录下的命令,都可以用npm run [命令]的格式运行。在命令行下,键入npm run,然后按tab键,就会显示所有可以使用的命令。

config

config 对象可以用来设置 package 脚本中使用的配置参数。

比如,一个 package 有如下配置:

1
2
3
4
5
6
7
8
9
{
"name": "foo",
"config": {
"port": "8080"
},
"scripts": {
"start": "node server.js"
}
}

然后,在 server.js 脚本中可引用 config字段的值:

1
2
3
4
http
.createServer(...)
.listen(process.env.npm_package_config_port)

然用户可通过执行 npm config set foo:port 8001 来覆盖。

dependencies

dependencies 字段指定了项目运行依赖的模块。

该对象的各个成员分别有模块名和对应的版本组成,表示依赖模块及其版本范围。版本范围遵循semver

1
2
3
4
5
6
{
"devDependencies": {
"browserify": "~13.0.0",
"karma-browserify": "~5.0.1"
}
}

请不要在依赖对象中放置测试用例或者转译器。

devDependencies

devDependencies 字段指定了项目开发所需要的模块。

该对象的各个成员分别有模块名和对应的版本组成,表示依赖模块及其版本范围。版本范围遵循semver

peerDependencies

该字段用来供插件指定去所需要的主工具的版本。

peerDependencies的目的是提示宿主环境去安装满足插件peerDependencies所指定依赖的包,然后在插件import或者require所依赖的包的时候,永远都是引用宿主环境统一安装的npm包,最终解决插件与所依赖包不一致的问题。

举例,我们使用 element-ui, element-ui的 package.json中有如下配置:

1
2
3
4
5
{
"peerDependencies": {
"vue": "^2.5.17"
}
}

它要求宿主环境安装指定版本的 vue 版本。

private

如果设置为 true,则可以防止应用程序/软件包被意外发布到 npm 上。

engines

设置此 package 或 项目要运行的 Node.js 或其他命令的版本。

1
2
3
4
5
6
7
{
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0",
"yarn": "^0.13.0"
}
}

结语

本片文章介绍了日常使用中使用频率较高的属性描述,如需查看全部属性,可查阅package.json

参考

  1. node.js入门教程
  2. package.json
  3. package.json文件
  4. 探讨npm依赖管理之peerDependencies