npm-hooks

衆所周知,npm是工程師們基於nodejs的開發中的核心內容。而大部分人在使用npm時,主要使用她的包管理系統。node

可是,當咱們稍微look look那些知名的開源項目,或者老牛們的代碼時,經常都能在它們的package.json裏看到一個寫滿了命令的scripts屬性。這裏面都隱藏了哪些祕密,牛牛們都用它作了什麼,怎麼作到的?這些疑問一定撕扯着你的好奇心,來,咱們今天就聊聊神祕的scripts屬性。git

Hooks(鉤子)

一般狀況下,應用程序只能處理來自內部的消息,若是但願對外部發來的消息也能攔截處理,那就須要一種叫鉤子(Hook)的技術。想象一下,npm test這個過程你是控制不了的,但若是就很是想在test以前自動處理點什麼事兒,怎麼辦?沒次都手動在test以前執行什麼,煩不煩、煩不煩、煩不煩?就是不煩,也會忘啊!github

這時候就用到咱們的Hook了。下面這些指令都是Hook,它們均可以在package.jsonscripts屬性裏定義,而且會在生命週期的某個指定時刻被執行,這就是上面提到的「對外部發來的消息也能攔截處理」,這極大的方便了開發人員(或許你想作點壞事兒?)npm

  • prepublish: 在publish該包以前執行。(在包目錄下執行npm install時也會執行)json

  • postpublish: 在該包publish以後執行post

  • preinstall: 在該包被install以前執行操作系統

  • postinstall: 在該包被install以後執行eslint

  • preuninstall: 在該包被uninstall以前執行rest

  • postuninstall: 在該包被uninstall以後執行code

  • preversion: 在修改該包的version以前執行

  • postversion: 在修改該包的version以後執行

  • pretest, posttest: 在該包內執行test時執行,其中pretest先於posttest

  • prestop, poststop: 在該包內執行stop時執行,其中prestop先於poststop

  • prestart,poststart: 在該包內執行start時執行,其中prestart先於poststart

  • prerestart, postrestart: 在該包內執行restart腳本時執行,其中prerestart先於postrestart。注意: 若是沒有在scripts裏顯示指定restart腳本,則會自動調用stop,而後再start

上面這些Hooks都是npm預約義好的,也就是說,當你執行npm install時,若是你在scripts裏定義了preinstallpostinstall,那它們分別會在npm install以前/後自動執行,不勞你操心!碉堡了,有木有?

還有,任何自定義腳本(經過npm run-script <腳本名>來執行)也能夠前綴prepost爲其製做鉤子。好比:premyscriptmyscriptpostmyscript

注:也可使用run做爲run-script的簡寫使用。

說說常見的使用場景1

若是你寫了一個類庫,有些操做和操做系統無關,但卻但願在該包被使用前執行,能夠試試prepublish,意思是,在你執行npm publish的時候,自動先執行scripts裏定義的prepublish裏的腳本。

舉個栗子:假設我用CoffeeScript寫了一個類庫,我有下面兩個願望:

  1. 我但願發佈的是JavaScript版本,這樣用戶npm install <類庫>以後無需搭建神馬亂七八糟的環境,便可直接使用

  2. 我但願發佈的是一個minified版本,即用戶npm install <類庫>以後,也可直接引入使用,而沒必要關心還要幫我壓縮一次

OK,咱們如今來聊聊這裏我用prepublish的好處:

  1. 這事兒執行一次就夠,就是我publish包的時候,不須要神馬用戶每次install的時候也作

  2. coffee-script能夠做爲devDependencies在個人項目裏,這樣的話,用戶在install這個類庫的時候,就不會下載coffee-script了。

  3. uglify-js也能夠做爲devDependencies在個人項目裏,好處同上

說說常見的使用場景2

再好比,寫了一個類庫,其中有些操做是和操做系統相關的,可使用postinstall看看。

那我以前寫的一個movoto-cli舉例,我有一個指望:
用戶在install個人類庫後,這個類庫要將兩個配置文件eslintrc_browser_legacy.jsoneslintrc_node.json裏的LINEBREAK_OS字段根據用戶的操做系統修改成正確的值。

因而我把這個操做寫在了postinstall這個Hook裏,問題解決,完美,沒問題!

Environment

常常聽到有朋友問到這樣的問題,說看到有人的scripts裏寫了"test": "mocha --reporter nyan",以爲這個代碼有漏洞,使用這個指令的人,必須得先npm install -g mocha(全局安裝mocha),不然test命令找不到mocha,會報錯的吧!

答案是這樣的,通常這麼寫scripts的,一般會把mocha裝在devDependencies或者dependencies裏。scripts裏的指令有這樣一個特色,若是你的類庫(或叫模塊)依賴的其它模塊提供了可執行腳本(譬如:mocha),那這些依賴會在你執行scripts指令時自動被注入到執行進程的PATH裏。

這就是說,若是devDependencies或者dependencies裏有mocha,那在npm test的時候,裏面的mocha命令,是從注入的PATH裏(即:node_modules/.bin/mocha)找了。

So,還須要全局安裝mocha麼?恐怕不須要了^^

本站公眾號
   歡迎關注本站公眾號,獲取更多信息