npm 脚本

npm 允许在package.json文件里面,使用scripts字段定义脚本命令。

  1. {
  2. // ...
  3. "scripts": {
  4. "build": "node build.js"
  5. }
  6. }
  7. // Vue
  8. "scripts": {
  9. "start": "vue-cli-service serve",
  10. "build": "vue-cli-service build",
  11. "lint": "vue-cli-service lint"
  12. },
  • 项目的相关脚本,可以集中在一个地方。
  • 不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。用户不需要知道怎么测试你的项目,只要运行npm run test即可。
  • 可以利用 npm 提供的很多辅助功能。
  • 使用不带任何参数的npm run命令

原理

npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。
这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。

由于 npm 脚本的唯一要求就是可以在 Shell 执行,因此它不一定是 Node 脚本,任何可执行文件都可以写在里面。
npm 脚本的退出码,也遵守 Shell 脚本规则。如果退出码不是0,npm 就认为这个脚本执行失败。

通配符

  1. 由于 npm 脚本就是 Shell 脚本,因为可以使用 Shell 通配符。
  2. "lint": "jshint *.js"
  3. "lint": "jshint **/*.js"
  4. 上面代码中,*表示任意文件名,**表示任意一层子目录。
  5. 如果要将通配符传入原始命令,防止被 Shell 转义,要将星号转义。
  6. "test": "tap test/\*.js"

传参

  1. //向 npm 脚本传入参数,要使用--标明。
  2. "lint": "jshint **.js"
  3. //向上面的npm run lint命令传入参数,必须写成下面这样。
  4. $ npm run lint -- --reporter checkstyle > checkstyle.xml
  5. //也可以在package.json里面再封装一个命令。
  6. "lint": "jshint **.js",
  7. "lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"

执行顺序

  1. 如果 npm 脚本里面需要执行多个任务,那么需要明确它们的执行顺序。
  2. 如果是并行执行(即同时的平行执行),可以使用&符号。
  3. $ npm run script1.js & npm run script2.js
  4. 如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&符号。
  5. $ npm run script1.js && npm run script2.js
  6. 这两个符号是 Bash 的功能。
  7. 此外,还可以使用 node 的任务管理模块:script-runnernpm-run-allredrun

默认值

  1. 一般来说,npm 脚本由用户提供。但是,npm 对两个脚本提供了默认值。也就是说,这两个脚本不用定义,就可以直接使用。
  2. "start": "node server.js"
  3. "install": "node-gyp rebuild"
  4. 上面代码中,npm run start的默认值是node server.js
  5. 前提是项目根目录下有server.js这个脚本;npm run install的默认值是node-gyp rebuild
  6. 前提是项目根目录下有binding.gyp文件。

钩子

npm 脚本有pre和post两个钩子。举例来说,build脚本命令的钩子就是prebuildpostbuild

  1. "prebuild": "echo I run before the build script",
  2. "build": "cross-env NODE_ENV=production webpack",
  3. "postbuild": "echo I run after the build script"
  4. 用户执行npm run build的时候,会自动按照下面的顺序执行。
  5. npm run prebuild && npm run build && npm run postbuild
  6. //因此,可以在这两个钩子里面,完成一些准备工作和清理工作
  7. "clean": "rimraf ./dist && mkdir dist",
  8. "prebuild": "npm run clean",
  9. "build": "cross-env NODE_ENV=production webpack"