你要知道的 Npm Script 都在這里
在拿到一個項目之后,如何看入口文件,如何運行項目,我們都會找到 package.json 中的 script 。甚至在做項目做久之后,我們會自己寫一些腳本來給開發(fā)提效,但你知道 NPM 腳本能做什么嗎?你知道如何傳遞一個參數(shù)給腳本?你知道如何執(zhí)行某個腳本文件么?在這篇文章中,我將分享我如何充分利用 NPM 腳本。
介紹
NPM 腳本是 package.json 中定義的一組內(nèi)置腳本和自定義腳本。他們的目標是提供一種簡單的方法來執(zhí)行重復(fù)的任務(wù),比如:
啟動項目 打包項目 執(zhí)行單元測試,生成測試報告之類 ……
那如何定義一個NPM腳本?需要做的就是設(shè)置它的名稱,并在 package.json 文件的 script 屬性中編寫該腳本, 如下:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
值得注意的是,NPM 中所有依賴的 node_modules bin 都可以在腳本中直接訪問,就像在路徑中被引用的一樣。比如:
{
"scripts": {
"lint": "./node_modules/.bin/eslint .",
}
}
// 此寫法與上面效果相同
{
"scripts": {
"lint": "eslint ."
}
}
命令
現(xiàn)在我們可以在終端中執(zhí)行 npm run test 執(zhí)行對應(yīng)的 script 腳本, 如下:
? xxx npm run test
> xx@1.0.0 test /Users/beidan/Desktop/xxx
> echo "Error: no test specified" && exit 1
Error: no test specified
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xx@1.0.0 test: `echo "Error: no test specified" && exit 1`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xx@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/beidan/.npm/_logs/2021-02-19T06_40_42_472Z-debug.log
如果直接在終端中執(zhí)行 npm test, 也是可以得到一樣的結(jié)果
? xxx npm test
> xx@1.0.0 test /Users/beidan/Desktop/xxx
> echo "Error: no test specified" && exit 1
Error: no test specified
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xx@1.0.0 test: `echo "Error: no test specified" && exit 1`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xx@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/beidan/.npm/_logs/2021-02-19T06_40_42_472Z-debug.log
這是因為,有些腳本是內(nèi)置可以使用更短的命令來執(zhí)行,更容易記住。例如,下面所有的命令的效果都是一樣的:
npm run-script test
npm run test
npm test
npm t
同理, npm start 也是一樣
npm run-script start
npm run start
npm start
執(zhí)行多個腳本
我們可能想結(jié)合一些腳本并一起運行它們。為此,我們可以使用 && 或 &
要依次運行多個腳本,可以使用 && ,例如:
npm run lint && npm test
要并行運行多個腳本,可以使用& 例如:
npm run lint&npm test
注意:這僅適用于 Unix 環(huán)境。在 Windows 中,它將按順序運行。
因此,我們在實際項目中可以創(chuàng)建一個結(jié)合了兩個腳本的腳本,以此來簡化我們的操作,如下所示:
{
"scripts": {
"lint": "eslint .",
"test": "echo \"Error: no test specified\" && exit 1",
"ci": "npm run lint && npm test" // 此時 npm run ci 即會依次執(zhí)行 npm run lint , npm run test
}
}
pre & post
我們可以為任何腳本創(chuàng)建 “pre” 和 “post” 腳本,NPM會自動按順序運行它們。唯一的要求是腳本的名稱(后跟“pre”或“post”前綴)與主腳本匹配。例如:
{
"scripts": {
"prehello": "echo \"--Pre \"",
"hello": "echo \"Hello World\"",
"posthello": "echo \"--post\""
}
}
如果我們執(zhí)行 npm run hello, npm 會按以下順序執(zhí)行腳本:prehello, hello, posthello。輸出如下:
? xxx npm run hello
> [email protected] prehello /Users/beidan/Desktop/xxx
> echo "--Pre "
--Pre
> [email protected] hello /Users/beidan/Desktop/xxx
> echo "Hello World"
Hello World
> [email protected] posthello /Users/beidan/Desktop/xxx
> echo "--post"
--post
錯誤
當腳本以非 0 退出碼結(jié)束時,這意味著在運行腳本的時候發(fā)生了錯誤,并終止了執(zhí)行。比如:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
那么在腳本拋出錯誤時,我們會得到一些其他的細節(jié),比如錯誤號 error 和代碼,具體的錯誤日志路徑都可以在終端獲取到,如下:
? xxx npm run test
> xx@1.0.0 test /Users/beidan/Desktop/xxx
> echo "Error: no test specified" && exit 1
Error: no test specified
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xx@1.0.0 test: `echo "Error: no test specified" && exit 1`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xx@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/beidan/.npm/_logs/2021-02-19T06_48_18_141Z-debug.log
靜默消息
如果想減少錯誤日志并非防止腳本拋出錯誤, 可以使用下面的命令來“靜默”處理, (比如在 ci 中,即使測試命令失敗,也希望整個管道繼續(xù)運行,就可以使用這個命令)
npm run <script> --silent
// 或者
npm run <script> -s
如果腳本名不存在時不想報錯,可以使用 --if-present ,比如:
npm run <script> --if-present
日志等級
我們可以使用--silent減少日志,但是如何獲得更詳細的日志呢?還是介于兩者之間?
有不同的日志級別:
"silent", "error", "warn", "notice", "http", "timing", "info", "verbose", "silly".
默認值為“ notice”。日志級別確定哪些日志將顯示在輸出中。將顯示比當前定義更高級別的任何日志。
我們可以使用--loglevel
現(xiàn)在,如果我們想獲取更詳細的日志,則需要使用比默認級別更高的級別(“notice”)。例如:
--loglevel <info>
我們還可以使用一些簡短的版本來簡化命令:
-s, --silent, --loglevel silent
-q, --quiet, --loglevel warn
-d, --loglevel info
-dd, --verbose, --loglevel verbose
-ddd, --loglevel silly
因此,要獲得最高級別的詳細信息,我們可以使用下面的命令
npm run <script> -ddd
// 或
npm run <script> --loglevel silly
從文件中引用路徑
如果腳本很復(fù)雜的話,在 package.json 中維護明顯會越來越冗長,也越來越難維護,因此復(fù)雜的腳本我們一般會寫在文件中,在 從文件中執(zhí)行腳本。如下:
{
"scripts": {
"hello:js": "node scripts/helloworld.js",
"hello:bash": "bash scripts/helloworld.sh",
"hello:cmd": "cd scripts && helloworld.cmd"
}
}
我們使用 node <path.js> 來執(zhí)行 JS 文件,使用 bash <path.sh> 來執(zhí)行 bash 文件
值得注意的是,如果是 cmd 或 bat 文件, 則需要先 cd 導(dǎo)航到對應(yīng)的文件夾目錄,不能像 sh, js 文件一樣,直接執(zhí)行,否則會報錯。
訪問環(huán)境變量
在執(zhí)行 NPM 腳本時,NPM提供了一組我們可以使用的環(huán)境變量。我們可以使用
npm_config_<val> 或者 npm_package_<val>
例如:
{
"scripts": {
"config:loglevel": "echo \"Loglevel: $npm_config_loglevel\"",
}
}
終端輸出如下:
? xxx npm run config:loglevel
> [email protected] config:loglevel /Users/beidan/Desktop/xxx
> echo "Loglevel: $npm_config_loglevel"
Loglevel: notice
配置參數(shù)使用npm_config_前綴放入環(huán)境中。這里有一些例子:
我們可以使用下面的命令獲取 config
npm config ls -l
傳遞參數(shù)
在某些情況下,您可能需要向腳本傳遞一些參數(shù)。您可以使用命令末尾的 -- 來實現(xiàn)這一點。添加到腳本中的任何 -- 都會被轉(zhuǎn)換成一個帶有 npm 配置前綴的環(huán)境變量。例如:
npm run <script>---<argument>="value"
例子:
{
"scripts": {
"ttt": "echo \"ttt $npm_config_firstname!\""
}
}
? xxx npm run ttt --firstname=234 // 傳入
> [email protected] ttt /Users/beidan/Desktop/xxx
> echo "ttt $npm_config_firstname!"
ttt 234! //輸出的值
命名規(guī)則
前綴
有些開源項目我們可以看到,他的 script 腳本是帶有前綴的, 這也是一個好的命名規(guī)則, 通過:dev, :prod 來區(qū)分環(huán)境, 如下:
{
"scripts": {
"build:dev": "...", // 開發(fā)環(huán)境
"build:prod": "..." // 生產(chǎn)環(huán)境
}
}
