咱們都很熟悉的,經過 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 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_name
、npm_package_version
、npm_package_script_build
、npm_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_foo
和 npm_config_dev
來訪問。
如何使用這些環境變量? 若是你的腳本是 shell 腳本,能夠直接經過對應的環境變量名獲取變量值,若是是 node 腳本,能夠經過 nodejs 中的全局變量 process.env
獲取,好比獲取項目版本號可使用 process.env.npm_package_version
。
另外,須要注意的是,即便在子目錄下使用 npm run 命令,腳本也會在項目的根目錄下運行。若是你想要區分在哪裏使用的 npm run 命令,可使用 INIT_CWD 環境變量,該變量保存了 npm run 命令運行時目錄的絕對路徑。
上面提到了 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…