如何將npm做為構(gòu)建工具使用

npmscripts命令可以做其它構(gòu)建工具所用的一切事情,而且它更加簡(jiǎn)明、更加優(yōu)雅、更少的包依賴和更少的維護(hù)成本。

npm Script

首先,我需要講一下npm是如何管理我們的構(gòu)建腳本的。我們知道npm的構(gòu)建腳本有npm run-script這個(gè)命令(npm run是它的簡(jiǎn)寫(xiě)),npm run的第一個(gè)參數(shù)會(huì)關(guān)聯(lián)到scripts對(duì)象的一個(gè)屬性,它會(huì)將這個(gè)屬性的值做為一個(gè)命令在操作系統(tǒng)默認(rèn)的shell中執(zhí)行。例如,下面的這個(gè)package.json

{
  "name": "myproject",
  "devDependencies": {
    "jshint": "latest",
    "browserify": "latest",
    "mocha": "latest"
  },
  "scripts": {
    "lint": "jshint **.js",
    "test": "mocha test/"
  }
}

如果運(yùn)行npm run lint,npm將開(kāi)啟一個(gè)shell并執(zhí)行jshint **.js,如果運(yùn)行npm run test,npm將開(kāi)啟一個(gè)shell并執(zhí)行mocha test/。而這個(gè)shell環(huán)境已經(jīng)將你的node_modules/.bin文件夾添加到了PATH中,這意味著你安裝的任何依賴可以被直接執(zhí)行--換句話說(shuō),你沒(méi)有必要像./node_modules/.bin/jshint **.js或者$(npm bin)/jshint **.js這樣來(lái)指定它的路徑。

如果你在運(yùn)行npm run時(shí)沒(méi)有寫(xiě)任何參數(shù),那么npm將會(huì)把已經(jīng)有的所有命令列出來(lái),如:

Available scripts in the user-service package:
  lint
     jshint **.js
  test
    mocha test/

Shortcut script

為了方便使用,npm也提供了一些命令的快捷使用方式。如:npm testnpm start、npm stop命令等,它們可以省去run

Pre and Post Hooks

別外一個(gè)很酷的特性是,任何npmscript可以設(shè)置多個(gè)pre-post-鉤子。例如,如果你執(zhí)行npm run lint,盡管npm預(yù)先并不知道lint任務(wù)是什么,但它會(huì)立即運(yùn)行npm run prelint,然后再執(zhí)行npm run lint,最后再執(zhí)行npm run postlint。prepostscript也是exit-code-sensitive的,這意味著,如果你的pretestscript以一個(gè)非零退出碼退出,那么NPM先會(huì)立即停止,并且也不會(huì)執(zhí)行再testposttestscripts。

你不在一個(gè)已經(jīng)是pre-的script上再加一個(gè)pre-,例如,prepretest將會(huì)被忽略。

你也可以在npm中對(duì)一些內(nèi)部的命令使用pre-post-,如:install、uninstall、publishupdate。你不能覆蓋任何內(nèi)部命令的行為,但是你可以通過(guò)pre-post-來(lái)影響他們的行為。這意味著,你可以做像這樣一件很酷的事情:

"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中,另一個(gè)很酷的特性是:傳遞參數(shù)集合。如下:

"scripts": {
    "test": "mocha test/",
    "test:xunit": "npm run test -- --reporter xunit"
  }

通過(guò)這個(gè)配制,我們可以簡(jiǎn)單運(yùn)行npm run test,它將會(huì)執(zhí)行mocha test/,但是我們可以通過(guò)--前輟來(lái)擴(kuò)展它的參數(shù)。

例如,npm run test --anothertest.js將會(huì)執(zhí)行mocha test/ anothertest.js,或者更有用的如npm run test -- --grep parser將會(huì)?解析為mocha test/ --grep parser(它只會(huì)執(zhí)行名為parser的測(cè)試)。

NPM Config Variables

最后一件值得我們注意的事是,npmpackage.json中有一個(gè)config命令,它使得任意的一系列值可以被包裝成為一個(gè)在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中有一個(gè)reporter屬性,它的值為xunit。這里所有config的屬性都暴露給了環(huán)境變量,你可以通過(guò)加npm_package_config_這個(gè)前輟來(lái)訪問(wèn)它們。

在上面這個(gè)例子中,npm run test命令使用$npm_package_config_reporter變量來(lái)獲取configreporter的值。

運(yùn)行多個(gè)任務(wù)

GruntCulp這樣的構(gòu)建工具都具有將多個(gè)任務(wù)整合成一個(gè)任務(wù)的能力。而使用npm時(shí)你有兩種方式可以選擇,這取決于哪種語(yǔ)義更加附合你使用場(chǎng)景。如果你的任務(wù)是一個(gè)先決條件(例如,將js最小化之前我們要將所有的js代碼導(dǎo)到一個(gè)文件中),那么使用pre-post-鉤子會(huì)是更好的選擇。另外你還可以像下面這樣使用bash的&&操作符:

  "scripts": {
    "build": "npm run build:css && npm run build:js"
  }

讓我們來(lái)看下來(lái)這個(gè)例子:

我們的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"
  }

下面是幾個(gè)文件,只是為了在執(zhí)行它們時(shí)打印出信息,代碼如下:

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...");

當(dāng)我們執(zhí)行npm run build時(shí),程序執(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...

多個(gè)任務(wù)的流式調(diào)用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、什么是 npm 腳本? npm 允許在package.json文件里面,使用scripts字段定義腳本命令。 ...
    豬豬9527閱讀 421評(píng)論 0 0
  • 關(guān)鍵詞:npm 定義:npm 允許在package.json文件里面,使用scripts字段定義腳本命令。 上面代...
    ferrint閱讀 13,683評(píng)論 2 6
  • 什么是 NPM npm之于Node,就像pip之于Python,gem之于Ruby,composer之于PHP。 ...
    ihoey閱讀 6,367評(píng)論 2 36
  • 原文鏈接:http://www.itdecent.cn/p/6b816c609669 前傳 出于興趣最近開(kāi)始研究k...
    懸筆e絕閱讀 7,357評(píng)論 1 11
  • 4月的最后一天,我來(lái)了一場(chǎng)期待已久的騎行。剛剛突然想起來(lái),現(xiàn)在居然在做一件很是巧合的事情。四月份開(kāi)頭寫(xiě)過(guò)一篇文章...
    冰魚(yú)兒閱讀 548評(píng)論 0 1

友情鏈接更多精彩內(nèi)容