配置
1 | // 配置列表 |
NPM依赖包版本号~和^和*的区别
~ 会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0^ 会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0* 这意味着安装最新版本的依赖包
推荐使用~,只会修复版本的bug,比较稳定
使用^或者* ,更新后会有可能导致项目不稳定,
锁定依赖
可以将需要安装的模块版本前缀默认设置成波浪号(~):1
npm config set save-prefix="~"
对于那些偏执的认为任何更新(模块的行为)会破坏系统的人,可以配置npm仅安装精确版本号的模块:1
npm config set save-exact true
定义默认的npm init
使用 npm init 初始化一个新的项目,这个过程会提示输入很多项目的配置,并创建一个 package.json 文件。
如果不想每次开始一个新的项目都需要重新输入同样的信息,可以使用 -y 标记表示你能接受 package.json 文件的一堆默认值:1
npm init -y
也可以通过config设置一些的默认值:1
2npm config set init.author.name <name>
npm config set init.author.email <email>
安装及升级包
1 | // 只安装package.json配置中的dependencies包: |
也可以使用npm-check来检查npm依赖包是否有更新,错误以及不在使用的,也可以使用npm-check进行包的更新。
查看指定包的信息
1 | npm [show|view|info|v] <package name> |
查看安装包版本
1 | // 本地包 |
运行命令
npm run 可以运行 package.json 中script里面的脚本。
由于 npm 脚本就是 Shell 脚本,因此可以使用 Shell 通配符。*表示任意文件名,**表示任意一层子目录1
2"lint": "jshint *.js"
"lint": "jshint **/*.js"
如果要将通配符传入原始命令,防止被 Shell 转义,要将星号转义。1
"test": "tap test/\*.js"
命令传参
向 npm 脚本传入参数,要使用--标明。1
2
3"lint": "jshint **.js"
// 向上面的npm run lint命令传入参数,必须写成下面这样
npm run lint -- --reporter checkstyle > checkstyle.xml
也可以在package.json里面再封装一个命令。
1 | "lint": "jshint **.js", |
命令的执行顺序
如果 npm 脚本里面需要执行多个任务,那么需要明确它们的执行顺序。
如果是并行执行(即同时的平行执行),可以使用&符号。
1 | npm run script1.js & npm run script2.js |
如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&符号。
1 | npm run script1.js && npm run script2.js |
这两个符号是 Bash 的功能。此外,还可以使用 node 的任务管理模块:script-runner、npm-run-all、redrun。
钩子
npm 脚本有pre和post两个钩子。举例来说,build脚本命令的钩子就是prebuild和postbuild。1
2
3"prebuild": "echo I run before the build script",
"build": "cross-env NODE_ENV=production webpack",
"postbuild": "echo I run after the build script"
用户执行npm run build的时候,会自动按照下面的顺序执行。1
npm run prebuild && npm run build && npm run postbuild
可以在这两个钩子里面,完成一些准备工作和清理工作。下面是一个例子。1
2
3"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"
npm 默认提供下面这些钩子。
- prepublish,postpublish
- preinstall,postinstall
- preuninstall,postuninstall
- preversion,postversion
- pretest,posttest
- prestop,poststop
- prestart,poststart
- prerestart,postrestart
自定义的脚本命令也可以加上pre和post钩子。比如myscript这个脚本命令,也有premyscript和postmyscript钩子。不过,双重的pre和post无效,比如prepretest和postposttest是无效的。
注意,
prepublish这个钩子不仅会在npm publish命令之前运行,还会在npm install(不带任何参数)命令之前运行。这种行为很容易让用户感到困惑,所以npm 4引入了一个新的钩子prepare,行为等同于prepublish,而从npm 5开始,prepublish将只在npm publish命令之前运行。
npm 提供一个npm_lifecycle_event变量,返回当前正在运行的脚本名称,比如pretest、test、posttest等等。所以,可以利用这个变量,在同一个脚本文件里面,为不同的npm scripts命令编写代码。请看下面的例子。1
2
3
4
5
6
7
8
9
10
11
12
13const TARGET = process.env.npm_lifecycle_event;
if (TARGET === 'test') {
console.log(`Running the test task!`);
}
if (TARGET === 'pretest') {
console.log(`Running the pretest task!`);
}
if (TARGET === 'posttest') {
console.log(`Running the posttest task!`);
}
简写命令
四个常用的 npm 脚本有简写形式。
npm start是npm run startnpm stop是npm run stop的简写npm test是npm run test的简写npm restart是npm run stop && npm run restart && npm run start的简写
npm start和npm stop都比较好理解,而npm restart是一个复合命令,实际上会执行stop、restart、start三个命令,具体的执行顺序如下。
- prerestart
- prestop
- stop
- poststop
- restart
- prestart
- start
- poststart
- postrestart
获取package.json配置
npm 脚本有一个非常强大的功能,就是可以使用 npm 的内部变量。首先,通过npm_package_前缀,npm 脚本可以拿到package.json里面的字段。比如,下面是一个package.json。1
2
3
4
5
6
7{
"name": "foo",
"version": "1.2.5",
"scripts": {
"view": "node view.js"
}
}
那么,变量npm_package_name返回foo,变量npm_package_version返回1.2.5。1
2
3// view.js
console.log(process.env.npm_package_name); // foo
console.log(process.env.npm_package_version); // 1.2.5
上面代码中,我们通过环境变量process.env对象,拿到package.json的字段值。如果是 Bash 脚本,可以用$npm_package_name和$npm_package_version取到这两个值。
npm_package_前缀也支持嵌套的package.json字段。1
2
3
4
5
6
7"repository": {
"type": "git",
"url": "xxx"
},
scripts: {
"view": "echo $npm_package_repository_type"
}
上面代码中,可以通过npm_package_repository_type取到repository字段的type属性。
下面是另外一个例子。1
2
3"scripts": {
"install": "foo.js"
}
上面代码中npm_package_scripts_install变量的值等于foo.js。
获取全局配置
npm 脚本还可以通过npm_config_前缀,拿到 npm 的配置变量,即npm config get xxx命令返回的值。比如,当前模块的发行标签,可以通过npm_config_tag取到。1
"view": "echo $npm_config_tag"
注意package.json里面的config对象,可以被环境变量覆盖。1
2
3
4
5{
"name" : "foo",
"config" : { "port" : "8080" },
"scripts" : { "start" : "node server.js" }
}
上面代码中,npm_package_config_port变量返回的是8080。这个值可以用下面的方法覆盖。1
$ npm config set foo:port 80
最后,npm run env命令可以列出所有环境变量。