也許你不知道的npm-scripts

kouchao發表於2019-04-11

前言

昨天發了一篇文章《記一次gitHook帶來的思考?》,發現npminstalluninstall的時候可以執行指令碼,@羽葉丶大佬評論說,可以繼續思考下 為何裝包時可以執行指令碼命令。於是乎今天就去看了一下昨天的主角yorkie,再它的package.json中發現了線索

{
  "scripts": {
    "install": "node bin/install.js",
    "uninstall": "node bin/uninstall.js"
  }
}
複製程式碼

開始思考

scripts我們應該都知道,可以使用npm run xxx來幫助我們完成一些事情。從昨天的發現到今天的探索來看,scripts很有可能還充當著生命週期的角色。開始查閱npm-scripts文件,看到的結果大吃一驚。原來我們熟知和經常使用的npm run xxx在文件中成為"另外,可以通過這種方式執行任意指令碼"。下面看一下也許你不知道的npm-scripts:

scripts的屬性

生命週期scripts

  • prepublish:在打包和釋出包之前執行,在npm install沒有任何引數的本地執行。
  • prepare:在打包和釋出包之前執行,在本地npm install:沒有任何引數,以及安裝git依賴項時執行。這是在之後執行prepublish,但是之前prepublishOnly
  • prepublishOnly:僅在準備和打包之前執行npm publish
  • prepack:前執行壓縮包(npm packnpm publish並安裝git的依賴時)
  • postpack:在生成壓縮包並移動到其最終目的地之後執行。
  • publish postpublish:釋出包後執行
  • preinstall:包安裝之前執行
  • install postinstall:包安裝後執行。預設:node-gyp rebuild,如果binding.gyp包的根目錄中有一個檔案而您尚未定義自己的指令碼installpreinstall指令碼,npm將預設install使用node-gyp進行編譯。
  • preuninstall uninstall:在包解除安裝之前執行。
  • postuninstall:在包解除安裝之後執行。
  • preversion:在碰撞包版本之前執行。
  • version:碰撞包版本之後,但提交之前執行。
  • postversion:碰撞包版本之後,提交之後執行。

主動呼叫

  • pretest test posttest:由npm test命令執行。
  • prestop stop poststop:由npm stop命令執行。
  • prestart start poststart:由npm start命令執行。預設:node server.js
  • prerestart restart postrestart:按npm restart命令執行。注意:npm restart 如果沒有restart提供指令碼,將執行停止和啟動指令碼。 -preshrinkwrap shrinkwrap postshrinkwrap:由npm shrinkwrap命令執行。

其他發現

神祕的.bin

你可能發現有這樣一個目錄node_modules/.bin,在裡面有webpack vue-cli-service這些常見的檔案,為什麼會有呢?跟上面所說的scripts有一定關係

執行npm start來執行指令碼,在npm install時,指令碼會匯出到node_modules/.bin目錄中。

比如node_modules/.bin中存在指令碼vue-cli-service

{
  "scripts": {
    "serve": "vue-cli-service serve --open",
  }
}
複製程式碼

package變數

比如 package.json中存在

{
  "name": "test"
}

process.env.npm_package_name // 值為test
複製程式碼

說到這,想到一個問題,yorkie要求我們在package.json中填寫gitHooks欄位,是不是通過這種方式獲取的呢?看了一下原始碼並不是。

const pkg = fs.readFileSync(path.join(cwd, 'package.json'))
const hooks = JSON.parse(pkg).gitHooks
複製程式碼

鉤子指令碼

git擁有鉤子指令碼目錄為.git/hooksnpm也有鉤子指令碼node_modules/.hooks/{eventname}其中evennamescripts欄位中的。在這定義的hook將會運用到專案中所有的包。

最後的話

希望大家多多指教,有什麼問題歡迎評論區見,在接受批評中共同成長,共同進步。

參考資料

相關文章