@yangfch3
2016-02-20T20:13:06.000000Z
字数 4181
阅读 14963
node
npm
不仅可以用于 模块管理,还可以用于 执行脚本。
package.json
文件有一个 scripts
字段,可以用于指定脚本命令,供 npm
直接调用。
{
"scripts": {
"commit": "sh commit.sh"
}
}
其中 commit.sh
文件内容为:
git add --all
git commit -m "common commit"
git push
接下来我们运行:
$ npm run commit
# 或
$ npm run-script commit
便相当于执行 sh commit.sh
任务
npm run
会创建一个新的shell
,执行指定的命令,并将node_modules/.bin
加入PATH
变量。当脚本内容结束,则子shell
关闭,回到父shell
中。请见:运行脚本的几种方式与区别
这两命令的效果都是一样的,都能执行 package.json
文件 scripts
字段下指定的任务。
npm run
是 npm run-script
的缩写,一般都使用 前者,但是后者可以更好地反应这个命令的本质。
直接运行 npm run
或 npm run-script
,不加参数会列出 scripts
属性下所有可运行的命令极其命令内容。
$ npm run
Available scripts in the user-service package:
commit
sh commit.sh
nodeIt
node demo.js
...
npm run
命令会自动在环境变量 $PATH
添加 node_modules/.bin
目录,所以 scripts
字段里面调用命令时不用加上路径。
所以我们在 package.json
文件内的 scripts
字段内指定任务的时候 一般 无需指定脚本文件的路径,只需要将脚本放到 ./node_module/.bin/
目录下即可,命令会在 这个目录 下自动寻找对应的脚本文件。而无需使用 ./node_modules/.bin/jshint **.js
当然你也可以更改与指定你需要运行的脚本的文件位置,如下:
"scripts": {
"nodeIt": "node demo/server.js",
"runcmd": "call demo/demo.cmd"
}
npm
内置了两个简写的命令,npm test
等同于执行 npm run test
,npm start
等同于执行 npm run start
。
这两个 test
、start
都可以在 scripts
字段下自己定义。
如果希望同时执行多个任务,可以借用 Linux
系统的 管道命令,将两个操作连在一起。
在 package.json
文件的 scripts
字段内的一个任务可以由多个子任务组成。
|
:连接两个任务
"build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js"
&&
:任务内部引用其他任务,子任务 先后 执行
"build": "npm run build-js && npm run build-css"
&
:任务内部引用其他任务,子任务 平行 执行
"commit": "npm run test & npm run commit"
流操作示例:
"scripts": {
"build-css": "autoprefixer -b 'last 2 versions' < assets/styles/main.css | cssmin > dist/main.css"
}
上面我们在 package.json
中定义了一个叫做 build-css
的任务,他又两个任务组成;当我们使用 npm run build-css
时会执行两个子任务(前提是这两个子任务的模块在本地或全局已安装,不报错)。
写在 scripts
属性中的命令,也可以在 node_modules/.bin
目录中直接写成 bash
脚本。下面是一个 bash
脚本(命名为:build-js.sh
)。
#!/bin/bash
cd site/main
browserify browser/main.js | uglifyjs -mc > static/bundle.js
我们在 package.json
内定义执行该脚本的命令:
"scripts": {
"build-js": "sh bin/build-js.sh"
}
并且需要设置脚本文件权限为可执行。
之后我们只需要运行:
npm run build-js
即可自动执行我们建立好的脚本!
npm
搭配脚本是十分方便的一件事情,也是我们提高效率的一大利器!
关于 bash
脚本的书写,请看此文
npm run
命令还可以接参数。
package.json
:在 newTxt
任务中未指定具体执行的脚本
"script": {
"newTxt": "sh"
}
我们在 node_module/.bin/
下新建一个待会要传入 newTxt
任务的脚本文件 newTxt.sh
:
touch newTxt.txt
然后我们运行:
npm run newTxt -- newTxt.sh
这样,newTxt.sh
便会作为参数传入我们的 newTxt
任务。
因为一个命令可以执行多个脚本:所以传入的参数并不会覆盖原来的参数,而是并行(或先后)执行。
"scripts": {
"test": "mocha test/"
}
$ npm run test -- anothertest.js
# 等同于
$ mocha test/ anothertest.js
上面命令表示,mocha
要运行所有 test
子目录的测试脚本,以及 另外一个测试脚本 anothertest.js
。
传入参数的格式:--
在参数之前加入 --
并用空格使命令与参数隔开
其他参数:
npm run
本身有一个参数-s,表示关闭 npm
工具本身的输出,只输出脚本产生的结果。
// 输出npm命令头信息
$ npm run test
// 不输出npm命令头
$ npm run -s test
这是一个用于方便地运行多个 scripts
脚本的命令。
安装:npm install npm-run-all --save-dev
$ npm-run-all build:html build:js
# 继发执行 build:html 和 build:js 两个任务;等同于
# $ npm run build:html && npm run build:js
--parallel
$ npm-run-all --parallel watch:html watch:js
# 等同于
# $ npm run watch:html & npm run watch:js
$ npm-run-all clean lint --parallel watch:html watch:js
# 等同于
# $ npm-run-all clean lint
# $ npm-run-all --parallel watch:html watch:js
$ npm-run-all --parallel watch:*
# 会并行执行所有符合 watch:* 的任务
start
脚本命令
一般用于项目的初始化,是接下来一切工作的依赖起始端
dev
脚本命令
规定开发阶段所要做的处理,比如监视文件变化、实时编译……
server
脚本命令
一般用于启动服务
test
脚本命令
一般用于执行测试:单元测试、*-lint
……
prod
脚本命令
一般用于规定进入生产环境时需要做的处理
help
脚本命令
help
脚本命令一般用于展示帮助信息。
docs
脚本命令
docs
脚本命令一般用于生成文档。
npm run
为每条命令提供了 pre-
和 post-
两个钩子(hook
)。以 npm run test
为例,如果我们的 scripts
字段规定了 pretest
和 posttest
:
"scripts": {
"test": "mocha test/",
"pretest": "echo test started!",
"posttest": "echo test end!"
}
则会先执行 pretest
任务,再执行 test
任务,完成 test
任务后即执行 posttest
任务。
可以简单的将二者理解为:预执行、后执行
scripts
字段可以使用一些内部变量,主要是 package.json
的各种字段。内部变量的主要特征是 $npm_package_key
。
比如,package.json
的内容是 {"name":"foo", "version":"1.2.5"}
,那么变量 $npm_package_name
的值是 foo
,变量 npm_package_version
的值是 1.2.5
。
{
"version": "1.2.5",
"scripts":{
"bundle": "mkdir -p build/$npm_package_version/"
}
}
运行 npm run bundle
以后,将会生成 build/1.2.5/
子目录。
config
字段也可以用于设置内部字段。
"name": "fooproject",
"config": {
"port": "3001"
},
"scripts": {
"serve": "http.createServer(...).listen(process.env.$npm_package_config_port)"
}
上面代码中,变量 npm_package_config_port
对应的就是 3001
。
*
匹配 0 个或多个字符?
匹配 1 个字符[...]
匹配某个范围的字符。如果该范围的第一个字符是 !
或 ^
,则匹配不在该范围的字符。!(pattern|pattern|pattern)
匹配任何不符合给定的模式?(pattern|pattern|pattern)
匹配 0 个或 1 个给定的模式+(pattern|pattern|pattern)
匹配 1 个或多个给定的模式*(a|b|c)
匹配 0 个或多个给定的模式@(pattern|pat*|pat?erN)
只匹配给定模式之一**
如果出现在路径部分,表示0个或多个子目录。