npm scripts 使用

一壁肋、什么是 npm 腳本?

npm 允許在package.json文件里面,使用scripts字段定義腳本命令。

{// ..."scripts":{"build":"node build.js"}}

上面代碼是package.json文件的一個片段柠并,里面的scripts字段是一個對象。它的每一個屬性富拗,對應(yīng)一段腳本堂鲤。比如,build命令對應(yīng)的腳本是node build.js媒峡。

命令行下使用npm run命令,就可以執(zhí)行這段腳本葵擎。

$ npm run build# 等同于執(zhí)行$ node build.js

這些定義在package.json里面的腳本谅阿,就稱為 npm 腳本。它的優(yōu)點很多。

1. 項目的相關(guān)腳本签餐,可以集中在一個地方寓涨。

2. 不同項目的腳本命令,只要功能相同氯檐,就可以有同樣的對外接口戒良。用戶不需要知道怎么測試你的項目,只要運行npm run test即可冠摄。

3. 可以利用 npm 提供的很多輔助功能糯崎。

查看當前項目的所有 npm 腳本命令,可以使用不帶任何參數(shù)的npm run命令河泳。

$ npm run

二沃呢、原理

npm 腳本的原理非常簡單。每當執(zhí)行npm run拆挥,就會自動新建一個 Shell薄霜,在這個 Shell 里面執(zhí)行指定的腳本命令。因此纸兔,只要是 Shell(一般是 Bash)可以運行的命令惰瓜,就可以寫在 npm 腳本里面。

比較特別的是汉矿,npm run新建的這個 Shell崎坊,會將當前目錄的node_modules/.bin子目錄加入PATH變量,執(zhí)行結(jié)束后负甸,再將PATH變量恢復(fù)原樣流强。

這意味著,當前目錄的node_modules/.bin子目錄里面的所有腳本呻待,都可以直接用腳本名調(diào)用打月,而不必加上路徑。比如蚕捉,當前項目的依賴里面有 Mocha奏篙,只要直接寫mocha test就可以了。

"test":"mocha test"

而不用寫成下面這樣迫淹。

"test":"./node_modules/.bin/mocha test"

由于 npm 腳本的唯一要求就是可以在 Shell 執(zhí)行秘通,因此它不一定是 Node 腳本,任何可執(zhí)行文件都可以寫在里面敛熬。

npm 腳本的退出碼肺稀,也遵守 Shell 腳本規(guī)則。如果退出碼不是0应民,npm 就認為這個腳本執(zhí)行失敗话原。

三夕吻、通配符

由于 npm 腳本就是 Shell 腳本,因為可以使用 Shell 通配符繁仁。

"lint":"jshint *.js""lint":"jshint **/*.js"

上面代碼中涉馅,*表示任意文件名,**表示任意一層子目錄黄虱。

如果要將通配符傳入原始命令稚矿,防止被 Shell 轉(zhuǎn)義,要將星號轉(zhuǎn)義捻浦。

"test":"tap test/\*.js"

四晤揣、傳參

向 npm 腳本傳入?yún)?shù),要使用--標明默勾。

"lint":"jshint **.js"

向上面的npm run lint命令傳入?yún)?shù)碉渡,必須寫成下面這樣。

$ npm run lint----reporter checkstyle> checkstyle.xml

也可以在package.json里面再封裝一個命令母剥。

"lint":"jshint **.js","lint:checkstyle":"npm run lint -- --reporter checkstyle > checkstyle.xml"

五滞诺、執(zhí)行順序

如果 npm 腳本里面需要執(zhí)行多個任務(wù),那么需要明確它們的執(zhí)行順序环疼。

如果是并行執(zhí)行(即同時的平行執(zhí)行)习霹,可以使用&符號。

$ npm run script1.js& npm run script2.js

如果是繼發(fā)執(zhí)行(即只有前一個任務(wù)成功炫隶,才執(zhí)行下一個任務(wù))淋叶,可以使用&&符號。

$ npm run script1.js&& npm run script2.js

這兩個符號是 Bash 的功能伪阶。此外煞檩,還可以使用 node 的任務(wù)管理模塊:script-runnernpm-run-all栅贴、redrun斟湃。

六、默認值

一般來說檐薯,npm 腳本由用戶提供凝赛。但是,npm 對兩個腳本提供了默認值坛缕。也就是說墓猎,這兩個腳本不用定義,就可以直接使用赚楚。

"start":"node server.js"毙沾,

"install":"node-gyp rebuild"

上面代碼中,npm run start的默認值是node server.js宠页,前提是項目根目錄下有server.js這個腳本搀军;npm run install的默認值是node-gyp rebuild膨俐,前提是項目根目錄下有binding.gyp文件。

七罩句、鉤子

npm 腳本有pre和post兩個鉤子。舉例來說敛摘,build腳本命令的鉤子就是prebuild和postbuild门烂。

"prebuild":"echo I run before the build script",

"build":"cross-env NODE_ENV=production webpack",

"postbuild":"echo I run after the build script"

用戶執(zhí)行npm run build的時候,會自動按照下面的順序執(zhí)行兄淫。

npm run prebuild&& npm run build&& npm run postbuild

因此屯远,可以在這兩個鉤子里面,完成一些準備工作和清理工作捕虽。下面是一個例子慨丐。

"clean":"rimraf ./dist && mkdir dist",

"prebuild":"npm run clean",

"build":"cross-env NODE_ENV=production webpack"

npm 默認提供下面這些鉤子。

1.? prepublish泄私,postpublish

2.? preinstall房揭,postinstall

3.? preuninstall,postuninstall

4.? preversion晌端,postversion

5.? pretest捅暴,posttest

6.? prestop,poststop

7.? prestart咧纠,poststart

8.? prerestart蓬痒,postrestart

自定義的腳本命令也可以加上pre和post鉤子。比如漆羔,myscript這個腳本命令梧奢,也有premyscript和postmyscript鉤子。不過演痒,雙重的pre和post無效亲轨,比如prepretest和postposttest是無效的。

npm 提供一個npm_lifecycle_event變量嫡霞,返回當前正在運行的腳本名稱瓶埋,比如pretest、test诊沪、posttest等等养筒。所以,可以利用這個變量端姚,在同一個腳本文件里面晕粪,為不同的npm scripts命令編寫代碼。請看下面的例子渐裸。

const TARGET = process.env.npm_lifecycle_event;

if(TARGET==='test'){

console.log(`Running the test task!`);

}

if(TARGET==='pretest'){

console.log(`Running the pretest task!`);

}

if(TARGET==='posttest'){

console.log(`Running the posttest task!`);

}

注意巫湘,prepublish這個鉤子不僅會在npm publish命令之前運行装悲,還會在npm install(不帶任何參數(shù))命令之前運行。這種行為很容易讓用戶感到困惑尚氛,所以 npm 4 引入了一個新的鉤子prepare诀诊,行為等同于prepublish,而從 npm 5 開始阅嘶,prepublish將只在npm publish命令之前運行属瓣。

八、簡寫形式

四個常用的 npm 腳本有簡寫形式讯柔。

npm start是npm run start

npm stop是npm run stop的簡寫

npm test是npm run test的簡寫

npm restart是npm run stop && npm run restart && npm run start的簡寫

npm start抡蛙、npm stop和npm restart都比較好理解,而npm restart是一個復(fù)合命令魂迄,實際上會執(zhí)行三個腳本命令:stop粗截、restart、start捣炬。具體的執(zhí)行順序如下熊昌。

1. prerestart

2. prestop

3. stop

4. poststop

5. restart

6. prestart

7. start

8. poststart

9. postrestart

九、變量

npm 腳本有一個非常強大的功能遥金,就是可以使用 npm 的內(nèi)部變量浴捆。

首先,通過npm_package_前綴稿械,npm 腳本可以拿到package.json里面的字段选泻。比如,下面是一個package.json美莫。

{

"name":"foo",

"version":"1.2.5",

"scripts":{

????"view":"node view.js"

}

}

那么页眯,變量npm_package_name返回foo,變量npm_package_version返回1.2.5厢呵。

// view.js

console.log(process.env.npm_package_name);// foo

console.log(process.env.npm_package_version);// 1.2.5

上面代碼中窝撵,我們通過環(huán)境變量process.env對象,拿到package.json的字段值襟铭。如果是 Bash 腳本碌奉,可以用$npm_package_name和$npm_package_version取到這兩個值。

npm_package_前綴也支持嵌套的package.json字段寒砖。

"repository":{

????"type":"git",

????"url":"xxx"

},

scripts:{

????"view":"echo $npm_package_repository_type"

}

上面代碼中赐劣,repository字段的type屬性,可以通過npm_package_repository_type取到哩都。

下面是另外一個例子魁兼。

"scripts":{

????"install":"foo.js"

}

上面代碼中,npm_package_scripts_install變量的值等于foo.js漠嵌。

然后咐汞,npm 腳本還可以通過npm_config_前綴盖呼,拿到 npm 的配置變量,即npm config get xxx命令返回的值化撕。比如几晤,當前模塊的發(fā)行標簽,可以通過npm_config_tag取到侯谁。

"view":"echo $npm_config_tag",

注意锌仅,package.json里面的config對象,可以被環(huán)境變量覆蓋墙贱。

{

????"name":"foo",

????"config":{

????????"port":"8080"

????},

????"scripts":{

????????"start":"node server.js"

????}

}

上面代碼中,npm_package_config_port變量返回的是8080贱傀。這個值可以用下面的方法覆蓋惨撇。

$ npm configsetfoo:port80

最后,env命令可以列出所有環(huán)境變量府寒。

"env":"env"

十魁衙、常用腳本示例

// 刪除目錄

"clean":"rimraf dist/*",

// 本地搭建一個 HTTP 服務(wù)

"serve":"http-server -p 9090 dist/",

// 打開瀏覽器

"open:dev":"opener http://localhost:9090",

// 實時刷新

"livereload":"live-reload --port 9091 dist/",

// 構(gòu)建 HTML 文件

"build:html":"jade index.jade > dist/index.html",

// 只要 CSS 文件有變動,就重新執(zhí)行構(gòu)建

"watch:css":"watch 'npm run build:css' assets/styles/",

// 只要 HTML 文件有變動株搔,就重新執(zhí)行構(gòu)建

"watch:html":"watch 'npm run build:html' assets/html",

// 部署到 Amazon S3

"deploy:prod":"s3-cli sync ./dist/ s3: //example-com/prod-site/",

// 構(gòu)建 favicon

"build:favicon":"node scripts/favicon.js",

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剖淀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纤房,更是在濱河造成了極大的恐慌纵隔,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炮姨,死亡現(xiàn)場離奇詭異捌刮,居然都是意外死亡,警方通過查閱死者的電腦和手機舒岸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門绅作,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛾派,你說我怎么就攤上這事俄认。” “怎么了洪乍?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵眯杏,是天一觀的道長。 經(jīng)常有香客問我典尾,道長役拴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任钾埂,我火速辦了婚禮河闰,結(jié)果婚禮上科平,老公的妹妹穿的比我還像新娘。我一直安慰自己姜性,他們只是感情好瞪慧,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著部念,像睡著了一般弃酌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上儡炼,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天妓湘,我揣著相機與錄音,去河邊找鬼乌询。 笑死榜贴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的妹田。 我是一名探鬼主播唬党,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鬼佣!你這毒婦竟也來了驶拱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤晶衷,失蹤者是張志新(化名)和其女友劉穎蓝纲,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體房铭,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡驻龟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缸匪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翁狐。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖凌蔬,靈堂內(nèi)的尸體忽然破棺而出露懒,到底是詐尸還是另有隱情,我是刑警寧澤砂心,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布懈词,位于F島的核電站,受9級特大地震影響辩诞,放射性物質(zhì)發(fā)生泄漏坎弯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抠忘。 院中可真熱鬧撩炊,春花似錦、人聲如沸崎脉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽囚灼。三九已至骆膝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灶体,已是汗流浹背阅签。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蝎抽,地道東北人愉择。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像织中,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子衷戈,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • https://www.cnblogs.com/liuchuanfeng/p/6759698.html 一狭吼、什么是...
    bansers閱讀 572評論 1 0
  • 轉(zhuǎn)載自 npm scripts 使用指南 Node 開發(fā)離不開 npm,而腳本功能是 npm 最強大殖妇、最常用的功能...
    一本大書閱讀 718評論 1 2
  • 針對項目使用的npm刁笙,做一個簡單的原理和使用筆記。npm 允許在package.json文件里面谦趣,使用script...
    小棨閱讀 289評論 0 0
  • 在一定程度是疲吸,你無論如何都要使用npm,而同時npm提供了腳本功能前鹅,所以你在命令行中使用的命令都可以在 npm S...
    回涼_4161閱讀 466評論 0 0
  • 一摘悴、什么是 npm 腳本? npm 允許在package.json文件里面舰绘,使用scripts字段定義腳本命令蹂喻。 ...
    夢若小龍閱讀 442評論 0 0