npm 腳本 script

2021-10-29 10:53 更新

npm 如何處理腳本字段

描述

"scripts"你的屬性package.json文件支持許多內(nèi)置的腳本和他們的預(yù)設(shè)生命周期事件以及任意腳本。這些都可以通過(guò)運(yùn)行npm run-script <stage>npm run <stage>簡(jiǎn)稱來(lái)執(zhí)行?。前置和后?名稱匹配的命令將這些以及運(yùn)行(例如premyscript,?myscriptpostmyscript)。依賴項(xiàng)的腳本可以使用?npm explore <pkg> -- npm run <stage>.

前后腳本

要為"scripts"部分中定義的任何腳本創(chuàng)建“pre”或“post”腳本?package.json,只需創(chuàng)建另一個(gè)具有匹配名稱的腳本?并將“pre”或“post”添加到它們的開(kāi)頭。

{
  "scripts": {
    "precompress": "{{ executes BEFORE the `compress` script }}",
    "compress": "{{ run command to compress files }}",
    "postcompress": "{{ executes AFTER `compress` script }}"
  }
}

在本例中,npm run compress將按照描述執(zhí)行這些腳本。

生命周期腳本

有一些特殊的生命周期腳本僅在某些情況下發(fā)生。這些腳本發(fā)生除pre<event>,post<event>和?<event>腳本。

  • prepare,?prepublish,?prepublishOnly,?prepack,postpack

準(zhǔn)備(因?yàn)?code>npm@4.0.0)

  • 在包裝包裝之前的任何時(shí)間運(yùn)行,即在包裝期間npm publish?和npm pack
  • 在打包之前運(yùn)行
  • 在發(fā)布包之前運(yùn)行
  • npm install沒(méi)有任何參數(shù)的情況下在本地運(yùn)行
  • 之后運(yùn)行prepublish,但之前prepublishOnly
  • 注意:如果通過(guò) git 安裝的包包含prepare?腳本,則在打包和安裝包之前dependencies,devDependencies將安裝其和并運(yùn)行準(zhǔn)備腳本。
  • 由于npm@7這些腳本在后臺(tái)運(yùn)行。要查看輸出,運(yùn)行帶有:--foreground-scripts。

預(yù)發(fā)布(已棄用)

  • 不在期間運(yùn)行npm publish,但在npm ci?和期間運(yùn)行npm install。請(qǐng)參閱下文了解更多信息。

僅預(yù)發(fā)布

  • 在包準(zhǔn)備和打包之前運(yùn)行,僅在npm publish.

預(yù)包裝

  • 在打包 tarball 之前運(yùn)行(在“?npm pack”、“?npm publish”和安裝 git 依賴項(xiàng)時(shí))。注意:“?npm run pack”與“?npm pack”不同。"?npm run pack" 是用戶定義的任意腳本名稱,其中, "?npm pack" 是 CLI 定義的命令。郵包
  • 在 tarball 生成之后但在將其移動(dòng)到最終目的地之前運(yùn)行(如果有的話,publish 不會(huì)在本地保存 tarball)

準(zhǔn)備和預(yù)發(fā)布

棄用說(shuō)明:預(yù)發(fā)布

由于npm@1.1.71,npm CLI 已經(jīng)prepublishnpm publish和運(yùn)行了腳本npm install,因?yàn)檫@是準(zhǔn)備要使用的包的便捷方式(一些常見(jiàn)用例在下面的部分中描述)。在實(shí)踐中,它也變得非?;靵y。從 開(kāi)始npm@4.0.0,引入了一個(gè)新事件prepare,保留了這種現(xiàn)有行為。添加了一個(gè)新事件prepublishOnly作為過(guò)渡策略,以允許用戶避免現(xiàn)有 npm 版本的混亂行為并僅繼續(xù)運(yùn)行npm publish(例如,最后一次運(yùn)行測(cè)試以確保它們處于良好狀態(tài))。

請(qǐng)參閱https://github.com/npm/npm/issues/10074以獲得更長(zhǎng)的理由,并進(jìn)一步閱讀此更改。

用例

如果您需要在使用之前對(duì)您的包執(zhí)行操作,以不依賴于操作系統(tǒng)或目標(biāo)系統(tǒng)架構(gòu)的方式,請(qǐng)使用prepublish腳本。這包括以下任務(wù):

  • 將 CoffeeScript 源代碼編譯成 JavaScript。
  • 創(chuàng)建 JavaScript 源代碼的縮小版本。
  • 獲取您的包將使用的遠(yuǎn)程資源。

prepublish按時(shí)做這些事情的好處是它們可以在一個(gè)地方做一次,從而降低復(fù)雜性和可變性。此外,這意味著:

  • 你可以依靠coffee-scriptdevDependency,因此用戶不需要安裝它。
  • 您不需要在包中包含縮小器,從而為用戶減小尺寸。
  • 您不需要依賴您的用戶在目標(biāo)機(jī)器上擁有curlwget或其他系統(tǒng)工具。

生命周期操作順序

npm cache add

  • prepare

npm ci

  • preinstall
  • install
  • postinstall
  • prepublish
  • preprepare
  • prepare
  • postprepare

這些都在將模塊實(shí)際安裝到?node_modules中后按順序運(yùn)行,中間沒(méi)有發(fā)生任何內(nèi)部操作

npm diff

  • prepare

npm install

這些也會(huì)在你運(yùn)行時(shí)運(yùn)行?npm install -g <pkg-name>

  • preinstall
  • install
  • postinstall
  • prepublish
  • preprepare
  • prepare
  • postprepare

如果binding.gyp你的包的根目錄中有一個(gè)文件并且你沒(méi)有定義你自己的installpreinstall腳本,npm 將默認(rèn)install使用 node-gyp 編譯命令通過(guò)node-gyp rebuild

這些是從腳本運(yùn)行的?<pkg-name>

npm pack

  • prepack
  • prepare
  • postpack

npm publish

  • prepublishOnly
  • prepack
  • prepare
  • postpack
  • publish
  • postpublish
  • prepare?

期間不會(huì)運(yùn)行?--dry-run

npm rebuild

preinstall``install``postinstall``prepare``prepare?僅當(dāng)當(dāng)前目錄是符號(hào)鏈接時(shí)才運(yùn)行(例如,帶有鏈接的包)

npm restart

如果restart定義了腳本,則運(yùn)行這些事件,否則?stop,start如果存在,則都運(yùn)行,包括它們的pre和?post迭代)

  • prerestart
  • restart
  • postrestart

npm run <user defined>

  • pre<user-defined>
  • <user-defined>
  • post<user-defined>

npm start

  • prestart
  • start
  • poststart

如果server.js包的根目錄中有一個(gè)文件,那么 npm 會(huì)將start命令默認(rèn)為node server.js.?prestart并且?poststart在這種情況下仍會(huì)運(yùn)行。

npm stop

  • prestop
  • stop
  • poststop

npm test

  • pretest
  • test
  • posttest

關(guān)于缺少npm uninstall腳本的說(shuō)明

雖然 npm v6 有uninstall生命周期腳本,但 npm v7 沒(méi)有。刪除包的原因多種多樣,目前還沒(méi)有明確的方法可以為腳本提供足夠有用的上下文。

刪除軟件包的原因包括:

  • 一個(gè)用戶直接卸載了這個(gè)包
  • 用戶卸載了依賴包,因此正在卸載此依賴項(xiàng)
  • 用戶卸載了一個(gè)依賴包,但另一個(gè)包也依賴于這個(gè)版本
  • 此版本已與另一個(gè)版本合并為副本等等。
  • 由于缺乏必要的上下文,uninstall生命周期腳本沒(méi)有實(shí)現(xiàn),也不會(huì)起作用。

用戶

當(dāng) npm 以 root 身份運(yùn)行時(shí),腳本總是使用工作目錄所有者的有效 uid 和 gid 運(yùn)行。

環(huán)境

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

路徑

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

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

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

package.json 變量

package.json 字段被添加到npm_package_前綴上。因此,例如,如果您{"name":"foo", "version":"1.2.5"}的 package.json 文件中有,那么您的包腳本會(huì)將?npm_package_name環(huán)境變量設(shè)置為“foo”,并將其?npm_package_version設(shè)置為“1.2.5”。您可以在代碼中使用process.env.npm_package_name和?訪問(wèn)這些變量,process.env.npm_package_version對(duì)于其他字段,依此類推。

有關(guān)package-json.md包配置的更多信息,請(qǐng)參見(jiàn)。

當(dāng)前生命周期事件

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

對(duì)象按照這種格式扁平化,所以如果你?{"scripts":{"install":"foo.js"}}在 package.json 中有,那么你會(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將在生命周期的安裝和安裝后階段scripts/uninstall.js?被調(diào)用,并在包被卸載時(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"
  }
}

退出

通過(guò)將行作為腳本參數(shù)傳遞給sh.

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

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

最佳實(shí)踐

  • 不要以非零錯(cuò)誤代碼退出,除非你是認(rèn)真的。除了卸載腳本,這將導(dǎo)致 npm 操作失敗,并可能被回滾。如果故障很小或只會(huì)阻止某些可選功能,那么最好只打印警告并成功退出。
  • 盡量不要使用腳本來(lái)做 npm 可以為您做的事情。通讀?package.json以查看您可以通過(guò)簡(jiǎn)單地適當(dāng)描述您的包來(lái)指定和啟用的所有內(nèi)容。一般來(lái)說(shuō),這將導(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 有問(wèn)題的 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)