有時候,運行一個工程,可能需要執(zhí)行多個腳本。如需要執(zhí)行客戶端代碼的 webpack 打包,還要執(zhí)行服務(wù)端代碼的 webpack 打包,當服務(wù)端代碼進行 webpack 進行打包后,還要重新啟動服務(wù)器等。
本文就是基于這樣一個需求,使用 npm-run-all,better-npm-run 和 nodemon 來優(yōu)化 NPM 腳本。
基本配置
先滿足最基本的需求:配置客戶端和服務(wù)端代碼的 webpack 打包命令:
{
...
"scripts": {
"run:server":"node dist/server.js",
"dev:server": "cross-env PLANTFORM=SERVER ENV=DEVELOPMENT webpack --config build/webpack.config.js --watch",
"dev:client": "cross-env PLANTFORM=CLIENT ENV=DEVELOPMENT webpack --config build/webpack.config.js --watch",
"build:server": "cross-env PLANTFORM=SERVER ENV=PRODUCTION webpack --config build/webpack.config",
"build:client": "cross-env PLANTFORM=CLIENT ENV=PRODUCTION webpack --config build/webpack.config",
"update:check": "ncu",
"update": "ncu -a"
}
...
}
在命令行執(zhí)行 npm run dev:server 和 npm run dev:client 分別可以在服務(wù)端和客戶端使用 webpack 打包,并自動監(jiān)聽文件變化。執(zhí)行 npm run build:server 和 npm run build:client 分別可以在服務(wù)端和客戶端執(zhí)行生產(chǎn)環(huán)境構(gòu)建。
執(zhí)行 npm run run:server 可以運行服務(wù)器。
另外 update:check 和 update 兩個命令分別用來檢查 package.json 中依賴包的更新版本和強制更新 package.json 中的依賴。
配置完上面的命令后,就可以用來進行開發(fā)了。但是使用還比較麻煩:客戶端和服務(wù)端的構(gòu)建,需要分別開啟兩個命令行窗口,再加上啟動 Node 服務(wù)的窗口,一共三個窗口。同時,當服務(wù)端構(gòu)建的代碼發(fā)生變化后,無法自動重啟服務(wù)器,需要手動停止再運行服務(wù),可謂相當麻煩。
服務(wù)器自動重啟
讓我們先來解決服務(wù)器自動重啟的問題,這需要用到nodemon 這個包,類似的還有supervisor這個包,后面這個包有一段歷史了,但是作者已經(jīng)很久沒有更新了。推薦使用nodemon。
借助nodemon,優(yōu)化NPM腳本:
{
...
"scripts": {
"run:server":"nodemon --watch dist --exec node dist/server.js",
...
}
...
}
現(xiàn)在,當 dist 目錄發(fā)生變化,就可以自動重啟服務(wù)器了。
命令并行執(zhí)行
借助 nodemon,解決了服務(wù)器自動重啟的問題,但是三個命令行窗口還是很麻煩,我們可以借助 npm-run-all 這個包,來讓三個命令在一個命令行窗口中運行:
{
...
"scripts": {
"start": "npm-run-all --parallel dev:* run:server",
"build": "npm-run-all --parallel build:*",
···
}
...
}
我們在 scripts 中加了一個 start 和 build 命令,運行 npm run start 和 npm run build 就可以實現(xiàn)在一個命令行窗口中,并行執(zhí)行開發(fā)和生產(chǎn)環(huán)境中的命令。
--parallel 用來指定哪些命令需要并行執(zhí)行,支持通配符。
優(yōu)化腳本
上面我們已經(jīng)完成了想要的功能:服務(wù)器自動重啟和命令并行執(zhí)行。乍看 scripts 中的命令,很長很凌亂。對于這個問題,可以借助better-npm-run 這個包來進行優(yōu)化:
{
···
"scripts": {
"start": "better-npm-run start",
"build": "better-npm-run build",
"dev:server": "better-npm-run dev:server",
"dev:client": "better-npm-run dev:client",
"build:server": "better-npm-run build:server",
"build:client": "better-npm-run build:client",
"run:server": "better-npm-run run:server",
"update:check": "better-npm-run update:check",
"update": "better-npm-run update"
},
"betterScripts":{
"start": "npm-run-all --parallel dev:* run:server",
"build": "npm-run-all --parallel build:*",
"run:server": "nodemon --watch dist --exec node dist/server.js",
"update:check": "ncu",
"update": "ncu -a",
"dev:server":{
"command":"webpack --config build/webpack.config.js --watch",
"env":{
"PLANTFORM":"SERVER",
"ENV":"DEVELOPMENT"
}
},
"dev:client":{
"command":"webpack --config build/webpack.config.js --watch",
"env":{
"PLANTFORM":"CLIENT",
"ENV":"DEVELOPMENT"
}
},
"build:server":{
"command":"webpack --config build/webpack.config.js",
"env":{
"PLANTFORM":"SERVER",
"ENV":"PRODUCTION"
}
},
"build:client":{
"command":"webpack --config build/webpack.config.js",
"env":{
"PLANTFORM":"CLIENT",
"ENV":"PRODUCTION"
}
}
},
···
}
通過better-npm-run這個包,我們把腳本命令寫得更具有層次感,雖然代碼量增加了,但結(jié)構(gòu)更加清晰。
完。