你真的熟悉 npm-scripts 嗎?

咱們都很熟悉的,經過 npm run script-name 能夠執行 package.json 中 scripts 對象配置的腳本。可是,你或許不知道下面這些知識。html

下文中 npm-scirpt 指 package.json scripts 中配置的腳本命令。name-scirpt 指代某一個名字爲 name 的腳本命令。node

生命週期腳本/自定義腳本

當咱們使用命令 npm start 時,npm 會嘗試執行 package.json scripts 中配置的 start 腳本命令。start-script 的默認配置爲 "start": "node server.js"。因此若是項目根目錄下有 server.js 文件,那麼經過 npm start 會直接運行 server.js 中的代碼。python

除了 start-script ,當使用 npm start 命令時,npm 一樣會嘗試在 package.json scripts 中查找是否配置了 prestart,poststart 腳本命令。若是都配置了,npm 會按照如下順序執行腳本。linux

  • npm run prestart
  • npm run start
  • npm run poststart

相似的,npm test, npm restart, npm stop 都會按照以上的方式執行 scripts 中配置的對應腳本。同時 npm 會經過 npm_lifecycle_event 環境變量標識當前處於哪一階段(所謂的生命週期)。好比,在 prestart-script 腳本執行階段 npm_lifecycle_event 的值爲 "prestart",start-script 階段,值爲 "start",即 package.json scripts 對象配置的腳本名字。webpack

以上是 npm 內置命令對應的腳本執行邏輯,對於咱們平時最熟悉的自定義腳本,以上邏輯一樣適用。好比咱們配置了 "build": "webpack --mode=production",同時配置了 prebuild 以及 postbuild 腳本,當使用 npm run build 時,一樣會依次執行 prebuild-script、build-script、postbuild-script。web

任意腳本

咱們配置的腳本命令,如 "start": "node server.js"node server.js 會當作一行代碼傳遞給系統的 SHELL 去解釋執行。實際使用的 SHELL 可能會根據系統平臺而不一樣,類 UNIX 系統裏,如 macOS 或 linux 中指代的是 /bin/sh, 在 windows 中使用的是 cmd.exe。shell

既然是交給 SHELL 去解釋執行的,說明配置的腳本能夠是任意可以在 SHELL 中運行的命令,而不單單是 node 腳本或者 js 程序。即若是你的系統裏安裝了 python(或者說系統變量 PATH 裏能找到 python 命令),你也能夠將 scripts 配置爲 "myscript": "python xxx.py"npm

環境變量

上面提到了在使用 npm run script-name 命令時,npm 會設置一個環境變量 npm_lifecycle_event。實際上 npm 還會設置不少環境變量,經過內置命令 npm run env 能夠查看 npm 爲腳本運行時設置的全部環境變量。 其中 package.json 中設置的全部字段,都會被設置爲 npm_package_ 開頭的環境變量。若是你的 packge.json 設置以下json

{
  "name": "npm-demo",
  "version": "1.0.0",
  "script": {
    "build": "webpack --mode=production"
  },
  "files": ["src"]
}
複製代碼

則能夠獲得 npm_package_namenpm_package_versionnpm_package_script_buildnpm_package_files_0 等變量。注意上面 package.json 中對象和數組中每一個字段都會有對應的環境變量。windows

不止 package.json,npm 相關的全部配置也會有 npm_config_ 開頭的環境變量。你能夠經過 npm config ls -l 查看全部配置,其中包括了全部 npm 默認配置,npmrc 文件中的配置,以及命令行中的配置項。

如:npm run dev --foo bar --dev ,此時npm 會添加兩個配置項,設置 foo 爲 bar 以及 dev 爲 true,同時在 npm 腳本中能夠經過環境變量 npm_config_foonpm_config_dev 來訪問。

如何使用這些環境變量? 若是你的腳本是 shell 腳本,能夠直接經過對應的環境變量名獲取變量值,若是是 node 腳本,能夠經過 nodejs 中的全局變量 process.env 獲取,好比獲取項目版本號可使用 process.env.npm_package_version

另外,須要注意的是,即便在子目錄下使用 npm run 命令,腳本也會在項目的根目錄下運行。若是你想要區分在哪裏使用的 npm run 命令,可使用 INIT_CWD 環境變量,該變量保存了 npm run 命令運行時目錄的絕對路徑。

PATH

上面提到了 npm-script 執行前會設置一些環境變量,其中很重要的一個環境變量是 PATH。npm 會將項目 node_modules/.bin 的絕對路徑添加到環境變量 PATH 中。所以咱們能夠在 npm-script 中使用項目本地安裝的一些命令行工具。如上面設置的 build 腳本: "build": "webpack --mode=production"

只要咱們本地安裝了 webpack,就能夠在項目的 node_modules/.bin 路徑下看到 webpack 可執行文件。又由於 node_modules/.bin 路徑已經添加到 PATH 中,因此腳本運行時可以在 PATH 中找到 webpack 命令,從而順利執行。

最後,爲何 webpack 安裝後,可以在 node_modules/.bin 路徑下找到對應的可執行文件?能夠查看 docs.npmjs.com/files/packa…

Reference

docs.npmjs.com/cli/run-scr…

docs.npmjs.com/misc/script…

docs.npmjs.com/files/packa…

相關文章
相關標籤/搜索