package.json

::: 提示 关于package.json里所有字段的使用,可参考官方文档: NPM - package.jsonopen in new window :::

package.json文件是 NPM 包的描述文件,NPM 包的所有行为与包描述文件的字段息息相关。

与 CommonJS 包规范相比,NPM 的实现里的包描述文件多了authorbinmaindevDependencies四个字段。

version

包的version需要遵循Semantic Versioning(语义化版本)。

语义化版本

Reference:

版本格式

版本格式:主版本号.次版本号.修订号,版本号递增规则如下:

  • 主版本号:当你做了不兼容的 API 修改,
  • 次版本号:当你做了向下兼容的功能性新增,
  • 修订号:当你做了向下兼容的问题修正。

先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

先行版本

当要发布大版本或者核心的 Feature 时,但是又不能保证这个版本的功能 100% 正常。这个时候就需要通过发布先行版本。

比较常见的先行版本包括:内测版、灰度版本了和 RC 版本。Semver 规范中使用alphabetarc(以前叫做gama)来修饰即将要发布的版本。它们的含义是:

  • alpha: 内部版本
  • beta: 公测版本
  • rc: 即Release candiate,正式版本的候选版本

比如:1.0.0-alpha.0, 1.0.0-alpha.1, 1.0.0-beta.0, 1.0.0-rc.0, 1.0.p-rc.1等版本。 alpha, beta, rc后需要带上次数信息。

npm 包发布时修改版本号

通常我们发布一个包到 npm 仓库时,我们的做法是先修改package.json为某个版本,然后执行npm publish命令。 手动修改版本号的做法建立在你对 Semver 规范特别熟悉的基础之上,否则可能会造成版本混乱。 npm 考虑到了这点,它提供了相关的命令来让我们更好的遵从 Semver 规范:

  • 升级补丁版本号:npm version patch
  • 升级小版本号:npm version minor
  • 升级大版本号:npm version major

当执行npm publish时,会首先将当前版本发布到npm registry,然后更新dist-tags.latest的值为新版本。 当执行npm publish --tag=next时,会首先将当前版本发布到npm registry,并且更新dist-tags.next的值为新版本。 这里的next可以是任意有意义的命名(比如:v1.x、v2.x 等等)

scripts

scripts 里的参数传递

假设package.json文件里如下配置了scripts属性:

{
  "name": "script-tests",
  "version": "1.0.0",
  "description": "Foo Bar",
  "scripts": {
    "pm2": "node ./server/pm2.js"
  }
}
1
2
3
4
5
6
7
8

当在控制台执行npm run pm2 hello world后,实际上是执行了node ./server/pm2.js "hello" "world"命令,在./server/pm2.js文件里的输出如下:

// ./server/pm2.js
console.log('0', process.argv[0]) // 0 /Users/wind-stone/.nvm/versions/node/v11.10.0/bin/node
console.log('1', process.argv[1]) // 1 /Users/wind-stone/kuaishou/ug-node-h5/server/pm2.js
console.log('2', process.argv[2]) // 2 hello
console.log('3', process.argv[3]) // 3 world
1
2
3
4
5

bin

若是在package.json文件下定义了如下示例里的bin属性,该包安装时将建立符号链接,全局安装时将链接到prefix/bin,局部安装时将链接到./node_modules/.bin/

package.json文件:

{
  "name": "npm-bin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "bin": {
    "npm-bin": "./bin/npm-bin.js"
  },
  // 若只有一个可执行文件,可直接使用包名作为命令名称
  // "bin": "./bin/npm-bin.js",
  "author": "",
  "license": "ISC"
}
1
2
3
4
5
6
7
8
9
10
11
12
13

./bin/npm-bin.js文件:

#!/usr/bin/env node
console.log('输入参数为:')
for (let i = 0; i < 3; i++) {
  console.log(`process.argv[${i}]: ${process.argv[i]}`)
}
1
2
3
4
5

提示

npm-bin.js文件的最顶部,一定要添加#!/usr/bin/env node,这一行告诉系统,执行是需要哪个解释器。 详情请见:Stack Overflow - What exactly does “/usr/bin/env node” do at the beginning of node files?open in new window

在该项目根目录下执行npm i -g,全局安装该包。继续执行npm-bin命令,则npm-bin.js就会执行。

➜  npm-bin npm i -g
/Users/wind-stone/.nvm/versions/node/v11.10.0/bin/npm-bin -> /Users/wind-stone/.nvm/versions/node/v11.10.0/lib/node_modules/npm-bin/bin/npm-bin.js
+ npm-bin@1.0.0
added 1 package in 0.087s

➜  npm-bin npm-bin
输入参数为:
process.argv[0]: /Users/wind-stone/.nvm/versions/node/v11.10.0/bin/node
process.argv[1]: /Users/wind-stone/.nvm/versions/node/v11.10.0/bin/npm-bin
process.argv[2]: undefined
1
2
3
4
5
6
7
8
9
10

全局安装的 bin

可以看到,执行npm i -g之后,建立起了从/Users/wind-stone/.nvm/versions/node/v11.10.0/bin/npm-bin/Users/wind-stone/.nvm/versions/node/v11.10.0/lib/node_modules/npm-bin/bin/npm-bin.js的符号链接。

PS: 系统安装了nvm

局部安装的 bin

在常规项目的node_modules/.bin路径下执行ls -l命令,可以看到局部安装的vuepresswebpack等包的符号链接:

lrwxr-xr-x  1 wind-stone  staff  27 10 30 11:54 vuepress -> ../vuepress/bin/vuepress.js
lrwxr-xr-x  1 wind-stone  staff  25 10 22 20:15 webpack -> ../webpack/bin/webpack.js
1
2

警告

局部安装的包,其命令只能在项目脚本和package.jsonscripts字段里面使用, 如果想在命令行下调用,必须像下面这样。

# 项目的根目录下执行
node_modules/.bin/vuepress dev
1
2

module

module字段要指向的应该是一个基于 ES6 模块规范的使用 ES5 语法书写的模块。详见聊聊 package.json 文件中的 module 字段open in new window

dependencies

使用本地路径

{
  "name": "baz",
  "dependencies": {
    "bar1": "file:../foo/bar",
    "bar2": "file:./foo/bar",
    "bar3": "file:~/foo/bar",
    "bar4": "file:/foo/bar"
  }
}
1
2
3
4
5
6
7
8
9

详见:NPM - package.json - dependencies - Local Pathsopen in new window