npm
的scripts
命令可以做其它構(gòu)建工具所用的一切事情虑鼎,而且它更加簡明、更加優(yōu)雅冀惭、更少的包依賴和更少的維護成本震叙。
npm Script
首先掀鹅,我需要講一下npm
是如何管理我們的構(gòu)建腳本的。我們知道npm
的構(gòu)建腳本有npm run-script
這個命令(npm run
是它的簡寫)媒楼,npm run
的第一個參數(shù)會關(guān)聯(lián)到scripts
對象的一個屬性乐尊,它會將這個屬性的值做為一個命令在操作系統(tǒng)默認的shell
中執(zhí)行。例如划址,下面的這個package.json
:
{
"name": "myproject",
"devDependencies": {
"jshint": "latest",
"browserify": "latest",
"mocha": "latest"
},
"scripts": {
"lint": "jshint **.js",
"test": "mocha test/"
}
}
如果運行npm run lint
扔嵌,npm
將開啟一個shell
并執(zhí)行jshint **.js
,如果運行npm run test
夺颤,npm
將開啟一個shell
并執(zhí)行mocha test/
痢缎。而這個shell
環(huán)境已經(jīng)將你的node_modules/.bin
文件夾添加到了PATH
中,這意味著你安裝的任何依賴可以被直接執(zhí)行--換句話說世澜,你沒有必要像./node_modules/.bin/jshint **.js
或者$(npm bin)/jshint **.js
這樣來指定它的路徑独旷。
如果你在運行npm run
時沒有寫任何參數(shù),那么npm
將會把已經(jīng)有的所有命令列出來寥裂,如:
Available scripts in the user-service package:
lint
jshint **.js
test
mocha test/
Shortcut script
為了方便使用嵌洼,npm
也提供了一些命令的快捷使用方式。如:npm test
封恰、npm start
麻养、npm stop
命令等,它們可以省去run
诺舔。
Pre and Post Hooks
別外一個很酷的特性是鳖昌,任何npm
的script
可以設(shè)置多個pre-
和post-
鉤子。例如低飒,如果你執(zhí)行npm run lint
许昨,盡管npm
預(yù)先并不知道lint
任務(wù)是什么,但它會立即運行npm run prelint
逸嘀,然后再執(zhí)行npm run lint
车要,最后再執(zhí)行npm run postlint
允粤。pre
和post
script也是exit-code-sensitive
的崭倘,這意味著,如果你的pretest
script以一個非零退出碼退出类垫,那么NPM
先會立即停止司光,并且也不會執(zhí)行再test
和posttest
scripts。
你不在一個已經(jīng)是pre-
的script上再加一個pre-
悉患,例如残家,prepretest
將會被忽略。
你也可以在npm
中對一些內(nèi)部的命令使用pre-
和post-
售躁,如:install
坞淮、uninstall
茴晋、publish
和update
。你不能覆蓋任何內(nèi)部命令的行為回窘,但是你可以通過pre-
和post-
來影響他們的行為诺擅。這意味著,你可以做像這樣一件很酷的事情:
"scripts": {
"lint": "jshint **.js",
"build": "browserify index.js > myproject.min.js",
"test": "mocha test/",
"prepublish": "npm run build # also runs npm run prebuild",
"prebuild": "npm run test # also runs npm run pretest",
"pretest": "npm run lint"
}
Passing Arguments
在npm
中啡直,另一個很酷的特性是:傳遞參數(shù)集合烁涌。如下:
"scripts": {
"test": "mocha test/",
"test:xunit": "npm run test -- --reporter xunit"
}
通過這個配制,我們可以簡單運行npm run test
酒觅,它將會執(zhí)行mocha test/
撮执,但是我們可以通過--
前輟來擴展它的參數(shù)。
例如舷丹,npm run test --anothertest.js
將會執(zhí)行mocha test/ anothertest.js
抒钱,或者更有用的如npm run test -- --grep parser
將會?解析為mocha test/ --grep parser
(它只會執(zhí)行名為parser的測試)。
NPM Config Variables
最后一件值得我們注意的事是颜凯,npm
的package.json
中有一個config
命令继效,它使得任意的一系列值可以被包裝成為一個在scripts
中的環(huán)境變量。例如:
"name": "fooproject",
"config": {
"reporter": "xunit"
},
"scripts": {
"test": "mocha test/ --reporter $npm_package_config_reporter",
"test:dev": "npm run test --fooproject:reporter=spec"
}
這里装获,config
中有一個reporter
屬性瑞信,它的值為xunit
。這里所有config
的屬性都暴露給了環(huán)境變量穴豫,你可以通過加npm_package_config_
這個前輟來訪問它們凡简。
在上面這個例子中,npm run test
命令使用$npm_package_config_reporter
變量來獲取config
中reporter
的值精肃。
運行多個任務(wù)
像Grunt
和Culp
這樣的構(gòu)建工具都具有將多個任務(wù)整合成一個任務(wù)的能力秤涩。而使用npm
時你有兩種方式可以選擇,這取決于哪種語義更加附合你使用場景司抱。如果你的任務(wù)是一個先決條件(例如筐眷,將js最小化之前我們要將所有的js代碼導到一個文件中),那么使用pre-
和post-
鉤子會是更好的選擇习柠。另外你還可以像下面這樣使用bash的&&
操作符:
"scripts": {
"build": "npm run build:css && npm run build:js"
}
讓我們來看下來這個例子:
我們的package.json的scripts
代碼如下:
"scripts": {
"jslint": "node jslint.js",
"csslint": "node csslint.js",
"build:css": "node build-css.js",
"build:js": "node build-js.js",
"build": "npm run build:css && npm run build:js",
"prebuild:js": "npm run jslint",
"prebuild:css": "npm run csslint"
}
下面是幾個文件匀谣,只是為了在執(zhí)行它們時打印出信息,代碼如下:
jslint.js
console.log("jslint task running...");
csslint.js
console.log("csslint task running...");
build-css.js
console.log("build:css task running...");
build-js.js
console.log("build:js task running...");
當我們執(zhí)行npm run build
時资溃,程序執(zhí)行順序如下:
> npm run build:css && npm run build:js
> npm run csslint
> node csslint.js
csslint task running...
> node build-css.js
build:css task running...
> npm run jslint
> node jslint.js
jslint task running...
> node build-js.js
build:js task running...