[关闭]
@yangfch3 2016-02-20T12:13:06.000000Z 字数 4181 阅读 5501

npm scripts

node


npm 不仅可以用于 模块管理,还可以用于 执行脚本

package.json 文件有一个 scripts 字段,可以用于指定脚本命令,供 npm 直接调用。

  1. {
  2. "scripts": {
  3. "commit": "sh commit.sh"
  4. }
  5. }

其中 commit.sh 文件内容为:

  1. git add --all
  2. git commit -m "common commit"
  3. git push

接下来我们运行:

  1. $ npm run commit
  2. # 或
  3. $ npm run-script commit

便相当于执行 sh commit.sh 任务

npm run 会创建一个新的 shell,执行指定的命令,并将 node_modules/.bin 加入 PATH 变量。当脚本内容结束,则子 shell 关闭,回到父 shell 中。

请见:运行脚本的几种方式与区别


0. npm run & npm run-script

这两命令的效果都是一样的,都能执行 package.json 文件 scripts 字段下指定的任务。

npm runnpm run-script 的缩写,一般都使用 前者,但是后者可以更好地反应这个命令的本质。

直接运行 npm runnpm run-script,不加参数会列出 scripts 属性下所有可运行的命令极其命令内容。

  1. $ npm run
  2. Available scripts in the user-service package:
  3. commit
  4. sh commit.sh
  5. nodeIt
  6. node demo.js
  7. ...

1. 智能路径

npm run 命令会自动在环境变量 $PATH 添加 node_modules/.bin 目录,所以 scripts 字段里面调用命令时不用加上路径。

所以我们在 package.json 文件内的 scripts 字段内指定任务的时候 一般 无需指定脚本文件的路径,只需要将脚本放到 ./node_module/.bin/ 目录下即可,命令会在 这个目录 下自动寻找对应的脚本文件。而无需使用 ./node_modules/.bin/jshint **.js

当然你也可以更改与指定你需要运行的脚本的文件位置,如下:

  1. "scripts": {
  2. "nodeIt": "node demo/server.js",
  3. "runcmd": "call demo/demo.cmd"
  4. }

2. npm test & npm start

npm 内置了两个简写的命令,npm test 等同于执行 npm run testnpm start 等同于执行 npm run start

这两个 teststart 都可以在 scripts 字段下自己定义。


3. 管道式命令

如果希望同时执行多个任务,可以借用 Linux 系统的 管道命令,将两个操作连在一起。

package.json 文件的 scripts 字段内的一个任务可以由多个子任务组成。

  1. |:连接两个任务

    1. "build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js"
  2. &&:任务内部引用其他任务,子任务 先后 执行

    1. "build": "npm run build-js && npm run build-css"
  3. &:任务内部引用其他任务,子任务 平行 执行

    1. "commit": "npm run test & npm run commit"

流操作示例

  1. "scripts": {
  2. "build-css": "autoprefixer -b 'last 2 versions' < assets/styles/main.css | cssmin > dist/main.css"
  3. }

上面我们在 package.json 中定义了一个叫做 build-css 的任务,他又两个任务组成;当我们使用 npm run build-css 时会执行两个子任务(前提是这两个子任务的模块在本地或全局已安装,不报错)。


4. bash 脚本

写在 scripts 属性中的命令,也可以在 node_modules/.bin 目录中直接写成 bash 脚本。下面是一个 bash 脚本(命名为:build-js.sh)。

  1. #!/bin/bash
  2. cd site/main
  3. browserify browser/main.js | uglifyjs -mc > static/bundle.js

我们在 package.json 内定义执行该脚本的命令:

  1. "scripts": {
  2. "build-js": "sh bin/build-js.sh"
  3. }

并且需要设置脚本文件权限为可执行。

之后我们只需要运行:

  1. npm run build-js

即可自动执行我们建立好的脚本!

npm 搭配脚本是十分方便的一件事情,也是我们提高效率的一大利器!
关于 bash 脚本的书写,请看此文


5. 参数

npm run 命令还可以接参数。

package.json:在 newTxt 任务中未指定具体执行的脚本

  1. "script": {
  2. "newTxt": "sh"
  3. }

我们在 node_module/.bin/ 下新建一个待会要传入 newTxt 任务的脚本文件 newTxt.sh

  1. touch newTxt.txt

然后我们运行:

  1. npm run newTxt -- newTxt.sh

这样,newTxt.sh 便会作为参数传入我们的 newTxt 任务。

因为一个命令可以执行多个脚本:所以传入的参数并不会覆盖原来的参数,而是并行(或先后)执行。

  1. "scripts": {
  2. "test": "mocha test/"
  3. }
  1. $ npm run test -- anothertest.js
  2. # 等同于
  3. $ mocha test/ anothertest.js

上面命令表示,mocha 要运行所有 test 子目录的测试脚本,以及 另外一个测试脚本 anothertest.js

  1. // 输出npm命令头信息
  2. $ npm run test
  3. // 不输出npm命令头
  4. $ npm run -s test

6. scripts 脚本命令最佳实践

1. npm-run-all

这是一个用于方便地运行多个 scripts 脚本的命令。

安装:npm install npm-run-all --save-dev

  1. $ npm-run-all build:html build:js
  2. # 继发执行 build:html 和 build:js 两个任务;等同于
  3. # $ npm run build:html && npm run build:js
  1. $ npm-run-all --parallel watch:html watch:js
  2. # 等同于
  3. # $ npm run watch:html & npm run watch:js
  1. $ npm-run-all clean lint --parallel watch:html watch:js
  2. # 等同于
  3. # $ npm-run-all clean lint
  4. # $ npm-run-all --parallel watch:html watch:js
  1. $ npm-run-all --parallel watch:*
  2. # 会并行执行所有符合 watch:* 的任务

2. 常见脚本命令

  1. start 脚本命令
    一般用于项目的初始化,是接下来一切工作的依赖起始端

  2. dev 脚本命令
    规定开发阶段所要做的处理,比如监视文件变化、实时编译……

  3. server 脚本命令
    一般用于启动服务

  4. test 脚本命令
    一般用于执行测试:单元测试*-lint……

  5. prod 脚本命令
    一般用于规定进入生产环境时需要做的处理

  6. help 脚本命令
    help 脚本命令一般用于展示帮助信息。

  7. docs 脚本命令
    docs 脚本命令一般用于生成文档。

3. pre- 和 post- 脚本命令

npm run 为每条命令提供了 pre-post- 两个钩子(hook)。以 npm run test 为例,如果我们的 scripts 字段规定了 pretestposttest

  1. "scripts": {
  2. "test": "mocha test/",
  3. "pretest": "echo test started!",
  4. "posttest": "echo test end!"
  5. }

则会先执行 pretest 任务,再执行 test 任务,完成 test 任务后即执行 posttest 任务。

可以简单的将二者理解为:预执行后执行

4. 内部变量

scripts 字段可以使用一些内部变量,主要是 package.json 的各种字段。内部变量的主要特征是 $npm_package_key

比如,package.json 的内容是 {"name":"foo", "version":"1.2.5"},那么变量 $npm_package_name 的值是 foo,变量 npm_package_version 的值是 1.2.5

  1. {
  2. "version": "1.2.5",
  3. "scripts":{
  4. "bundle": "mkdir -p build/$npm_package_version/"
  5. }
  6. }

运行 npm run bundle 以后,将会生成 build/1.2.5/ 子目录。

config 字段也可以用于设置内部字段。

  1. "name": "fooproject",
  2. "config": {
  3. "port": "3001"
  4. },
  5. "scripts": {
  6. "serve": "http.createServer(...).listen(process.env.$npm_package_config_port)"
  7. }

上面代码中,变量 npm_package_config_port 对应的就是 3001

5. 通配规则

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注