您可以在這裡找到原始碼:https://github.com/aelassas/watcher
在使用 Node.js 應用程式時,您經常需要在進行一些更改後重新啟動伺服器。好吧,如果每次對原始程式碼進行一些修改時都必須手動重新啟動伺服器,這會很煩人。值得慶幸的是,有一些實用程式可以讓您在檢測到變更時自動重新啟動伺服器。而最著名的就是nodemon。 nodemon 是一個工具,可在偵測到目錄中的檔案變更時自動重新啟動節點應用程序,從而協助開發基於 Node.js 的應用程式。本技巧的目的不是重新發明輪子,而是向您展示如何創建自己的實用程式來監視 Node.js 應用程式中的任何更改,並僅用幾行程式碼即可自動重新啟動伺服器。
第一步是初始化我們的 Node.js 專案:
npm init
然後,我們必須更新 package.json 以便透過將模組設為 type:
來新增對 ES6 的支持{ "name": "watcher", "type": "module", "version": "1.0.0", "author": "Akram El Assas" }
然後,我們將安裝開發依賴項:
npm i -D @types/node
我們將建立一個簡單的網頁伺服器server.js,如下所示:
import { createServer } from 'http' const PORT = 8888 createServer((_, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.write('Hello World!') res.end() }).listen(PORT) console.log('HTTP server is running on Port', PORT)
然後,我們將建立一個觀察程序,以便每次透過以下命令在伺服器的父資料夾及其子資料夾中偵測到變更時重新啟動伺服器:
node watcher.js server.js
每次偵測到變更時,觀察者都會重新啟動伺服器。
首先也是最重要的,我們需要檢索命令列參數。在 Node.js 中,我們可以透過 process.argv 存取命令列參數。 process.argv 屬性傳回一個數組,其中包含啟動 Node.js 進程時傳遞的命令列參數。第一個元素是 execPath。第二個元素是正在執行的 JavaScript 檔案的路徑。其餘元素將是任何附加的命令列參數。
如果我們執行以下指令:
node watcher.js server.js
process.argv 如下:
[ 'C:\Program Files\nodejs\node.exe', 'C:\dev\watcher\src\watcher.js', 'server.js' ]
第一個元素是 Node.js 執行檔的路徑。第二個元素是 watcher.js 的路徑。最後一個元素是 server.js。因此,我們可以透過聲明第一個和第三個元素來開始我們的程式碼,如下所示:
npm init
然後我們需要建立一個函數來啟動一個子進程,該子進程使用指定檔案作為參數啟動 Node.js,在我們的例子中是 server.js。為此,我們將使用 child_process 模組中的 spawn 方法。 child_process.spawn() 方法使用給定指令產生一個新進程,並在 args 中使用命令列參數。使用spawn方法的優點是我們可以使用pipe方法將子程序的stdout和stderr重新導向到父進程。 Pipe 方法用於將可寫流附加到可讀流,以便它隨後切換到流動模式,然後將其擁有的所有資料推送到附加的可寫流。我們函數的原始碼如下所示:
{ "name": "watcher", "type": "module", "version": "1.0.0", "author": "Akram El Assas" }
首先,我們使用給定的檔案參數來產生一個 Node.js 子程序。然後,我們使用管道方法將子進程的stdout和stderr重新導向到父進程。然後,當子進程關閉時,我們使用相同的退出代碼退出父進程。 process.exit() 方法指示 Node.js 以程式碼的退出狀態同步終止進程。如果省略 code,則 exit 使用成功代碼 0 或 process.exitCode 的值(如果已設定)。在呼叫所有退出事件偵聽器之前,Node.js 不會終止。最後,我們返回子進程。
現在,我們需要偵測檔案的父資料夾及其子資料夾的變更。每次偵測到與 JavaScript 檔案相關的變更時,我們都會終止子進程並再次產生子進程。為此,我們將使用 fs/promises 模組中的 watch 方法。 fs/promises.watch() 方法傳回一個非同步迭代器,用於監視檔案名稱的更改,其中檔案名稱是檔案或目錄。我們將在文件的父資料夾上建立一個觀察程式。然後,我們將迭代觀察者。我們將忽略 node_modules 資料夾,每次在 JavaScript 檔案上偵測到變更時,我們將終止子進程並再次產生它,如下所示:
npm i -D @types/node
subprocess.kill() 方法向子程序發送訊號。如果沒有給予參數,進程將被傳送 SIGTERM 訊號。 SIGKILL 訊號無法被捕捉、封鎖或忽略,並且會強制子程序停止。請參閱 signal(7) 以取得可用訊號的清單。
就是這樣!我們只用幾行程式碼就完成了我們自己的nodemon。
最後但並非最不重要的一點是,我們需要將啟動和開發腳本添加到 package.json 中,如下所示:
import { createServer } from 'http' const PORT = 8888 createServer((_, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.write('Hello World!') res.end() }).listen(PORT) console.log('HTTP server is running on Port', PORT)
要啟動我們的應用程序,只需輸入以下命令:
node watcher.js server.js
現在,如果我們運行應用程式並對 server.js 進行更改,伺服器將自動重新啟動。我們不再需要手動停止和啟動伺服器。
我們只用幾行程式碼就設定了自己的nodemon。現在,我們的 watcher.js 的整個原始碼如下所示:
npm init
這只是一個簡單的範例,但您可以想像其他情況,您監視視訊檔案的更改,並且每次偵測到更改時,都會啟動轉換子進程(ffmpeg)。
您也可以實作其他選項,例如:
以上是用幾行程式碼建立自己的nodemon的詳細內容。更多資訊請關注PHP中文網其他相關文章!