npm 腳本 scripts

2021-10-29 10:53 更新

npm 如何處理腳本(Scripts)字段?

描述

npm 支持 package.json 文件的 "scripts" 屬性,適用于以下腳本:

  • 預(yù)發(fā)布(prepublish):在打包和發(fā)布包之前運(yùn)行,以及在沒有任何參數(shù)的本地 npm install 上運(yùn)行。(見下文)
  • 準(zhǔn)備(prepare): 在打包和發(fā)布包之前,在沒有任何參數(shù)的本地 npm install 上,以及在安裝 git 依賴項(xiàng)時(shí)運(yùn)行(見下文)。這是在預(yù)發(fā)布之后運(yùn)行,但在僅預(yù)發(fā)布之前。
  • 預(yù)發(fā)布(prepublishOnly):在準(zhǔn)備和打包包之前運(yùn)行,僅在 npm publish 上運(yùn)行。
  • 預(yù)打包(prepack):在打包 tarball 之前運(yùn)行(在 npm packnpm publish和安裝 git 依賴項(xiàng)時(shí)。)
  • 打包后(postpack):在 tarball 生成并移動(dòng)到其最終目的后運(yùn)行。
  • 發(fā)布,發(fā)布后(publish,postpublish):在發(fā)布包后運(yùn)行。
  • 預(yù)安裝(preinstall):在安裝包之前運(yùn)行。
  • 安裝,安裝后(install,postinstall):在安裝包后運(yùn)行。
  • 預(yù)卸載,卸載(preuninstall,uninstall):在卸載包之前運(yùn)行。
  • 卸載后(postuninstall):在卸載軟件包后運(yùn)行。
  • 預(yù)測(cè)版本(preversion):在碰撞包版本之前運(yùn)行。
  • 版本(version):在碰撞包版本后運(yùn)行,但在提交之前。
  • 提交版本(postversion):在碰撞包版本后運(yùn)行,并在提交后運(yùn)行。
  • 預(yù)測(cè)試,測(cè)試,測(cè)試后(pretest,test,posttest):通過 npm test 命令運(yùn)行。
  • 預(yù)停止,停止,停止后(prestop,stop,poststop):通過 npm stop 命令運(yùn)行。
  • 預(yù)啟動(dòng),啟動(dòng),啟動(dòng)后(prestart,start,poststart):通過 npm start 命令運(yùn)行。注意:如果沒有提供重啟腳本,npm restart 將運(yùn)行停止和啟動(dòng)腳本。
  • 預(yù)包裝,包裝,包裝后(preshrinkwrap,shrinkwrap,postshrinkwrap):通過 npm shrinkwrap 命令取消。

此外,可以通過運(yùn)行npm run-script<stage>來執(zhí)行任意腳本。具有匹配名稱的前置(pre)和后置(post)命令也將運(yùn)行(例如:premyscript,myscript,postmyscript)。來自依賴項(xiàng)的腳本可以使用npm explore <pkg> --npm run<stage>運(yùn)行。

預(yù)發(fā)布和與準(zhǔn)備(prepublish and prepare)

棄用說明

npm@1.1.71開始,npm CLI 為npm publishnpm install運(yùn)行了 prepublish 腳本,因?yàn)檫@是一種準(zhǔn)備要使用的包的便捷方式(一些常見用例在下面的部分中描述)。在實(shí)踐中,它也會(huì)變的非?;靵y。從npm@4.0.0開始,引入了一個(gè)新時(shí)間準(zhǔn)備,它保留了現(xiàn)有的行為。添加了一個(gè)新事件 prepublishOnly 作為過度策略,以允許用戶避免先用 npm 版本的混淆行為,并僅在 npm publish 上運(yùn)行(例如,最后一次運(yùn)行測(cè)試以確保它們處于良好狀態(tài))。

使用案例

npm 將根據(jù)包內(nèi)容默認(rèn)一些腳本值。

  • start:node server.js: 如果你的包的根目錄中有一個(gè) server.js 文件,那么 npm 會(huì)將啟動(dòng)命令默認(rèn)為 node server.js。
  • install:node-gyp rebuild: 如果你的包的根目錄中有一個(gè) binding.gyp 文件,并且你沒有定義自己的安裝和預(yù)安裝腳本,npm 將默認(rèn)安裝命令使用 node-gyp 進(jìn)行編譯。

    用戶

    如果 npm 是用 root 權(quán)限調(diào)用的,那么它會(huì)將 uid 更改為用戶 config 指定的用戶賬號(hào)或者 uid,默認(rèn)為nobody。設(shè)置unsafe-perm標(biāo)志以使用 root 權(quán)限運(yùn)行腳本。

環(huán)境

包腳本在一個(gè)環(huán)境中運(yùn)行,在該環(huán)境中提供了許多關(guān)于 npm 設(shè)置和進(jìn)程當(dāng)前狀態(tài)的信息。

路徑

如果您依賴于定義可執(zhí)行腳本的模塊,例如測(cè)試套件,那么這些可執(zhí)行文件將會(huì)被添加到 PATH 以執(zhí)行腳本。所以,如果你的 package.json 文件有這個(gè):

{"name":foot
,"dependencies":{"bar":"0.1.x"}
,"scripts":{"start":"bar ./test"}
}

然后你可以運(yùn)行npm start來執(zhí)行 bar 腳本,它在npm install上被導(dǎo)出到node_modules/.bin目錄中。

package.json 變量

package.json 字段被添加到npm_package_前綴上。因此,例如,如果您的 package.json 文件中有{"name":"foo","version":"1.2.5},那么您的包腳本會(huì)將npm_package_name環(huán)境變量設(shè)置為foot,并且npm_package_version設(shè)置為1.2.5。

package.json 對(duì)象

如果有<name>[@<version>]:<key>的配置參數(shù),package.json "config"鍵在環(huán)境中被覆蓋。例如,如果 package.json 有這個(gè):

{"name":"foo"
,"config":{"post":"8080"}
,"scripts:{"start":"node server.js"}}

server.js文件是這樣的:

http。createServer(...)。listen(process.env.npm_package_config_port)

然后用戶可以通過執(zhí)行以下的操作來更改行為:

npm config set foo:port 80

當(dāng)前生命周期時(shí)間

最后,將npm_lifecycle_event環(huán)境變量設(shè)置為正在執(zhí)行的循環(huán)階段。因此,您可以將單個(gè)腳本用于流程的不同部分,該腳本根據(jù)當(dāng)前發(fā)生的情況進(jìn)行切換。

對(duì)象按照這種格式扁平化,所以如果你的 package.json 中有 {"scripts":{"install":"foo.js"}},那么你會(huì)在腳本中看到:

process.env.npm_package_scripts_install === "foo.js"

示例

例如,如果您的 package.json 包含以下內(nèi)容:

{ "scripts" :
  { "install" : "scripts/install.js"
  , "postinstall" : "scripts/install.js"
  , "uninstall" : "scripts/uninstall.js"
  }
}

然后 scripts/install.js 將在生命周期的安裝和安裝后階段被調(diào)用,scripts/uninstall.js 將在包被卸載時(shí)被調(diào)用。由于 scripts/install.js 運(yùn)行了兩個(gè)不同的階段,因此在這種情況下查看 npm_lifecycle_event 環(huán)境變量是明智的。

如果你想運(yùn)行一個(gè) make 命令,你可以這樣做。這工作得很好:

{ "scripts" :
  { "preinstall" : "./configure"
  , "install" : "make && make install"
  , "test" : "make test"
  }
}

退出

通過將行作為腳本參數(shù)傳遞給 sh 來運(yùn)行腳本。

如果腳本以 0 以外的代碼退出,則這將中止進(jìn)程。

請(qǐng)注意,這些腳本文件不必是 nodejs 甚至 javascript 程序。它們只需要是某種可執(zhí)行文件。

鉤子腳本

如果要在所有包的特定生命周期事件中運(yùn)行特定腳本,則可以使用鉤子腳本。

將一個(gè)可執(zhí)行文件放在 node_modules/.hooks/{eventname} 中,當(dāng)所有軟件包在該根目錄中安裝的任何軟件包的軟件包生命周期中的那個(gè)點(diǎn)時(shí),它將為所有軟件包運(yùn)行。

Hook 腳本的運(yùn)行方式與 package.json 腳本完全相同。也就是說,它們位于一個(gè)單獨(dú)的子進(jìn)程中,具有上述 env。

最佳實(shí)踐

  • 不要以非零錯(cuò)誤代碼退出,除非您是認(rèn)真的。除了卸載腳本,這將導(dǎo)致 npm 操作失敗,并可能被回滾。如果故障很小或只會(huì)阻止某些可選功能,那么最好只打印警告并成功退出。
  • 盡量不要使用腳本來做 npm 可以為您做的事情。通讀?[package.json](http://www.o2fo.com/npmjs/npmjs-u56d3ku5.html)以查看您可以通過簡單地適當(dāng)描述您的包來指定和啟用的所有內(nèi)容。一般來說,這將導(dǎo)致更健壯和一致的狀態(tài)。
  • 檢查環(huán)境以確定放置東西的位置。例如,如果npm_config_binroot環(huán)境變量設(shè)置為/home/user/bin,則不要嘗試將可執(zhí)行文件安裝到/usr/local/bin.?用戶可能出于某種原因以這種方式進(jìn)行設(shè)置。
  • 不要在腳本命令前加上“sudo”。如果出于某種原因需要 root 權(quán)限,那么它會(huì)因該錯(cuò)誤而失敗,并且用戶將 sudo 有問題的 npm 命令。
  • 不要使用install.?使用.gyp文件進(jìn)行編譯,以及prepublish?其他任何事情。您幾乎不必顯式設(shè)置預(yù)安裝或安裝腳本。如果您正在這樣做,請(qǐng)考慮是否還有其他選擇。installpreinstall?腳本的唯一有效用途是編譯,必須在目標(biāo)架構(gòu)上完成。
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)