Rush Stack商店部落格活動
跳至主要內容

使用監看模式

諸如 WebpackJest 之類的常用工具,都提供「監看模式」功能:在工作完成後,工具會進入迴圈,監看檔案系統中原始程式碼檔案的變更。每當偵測到變更時,工作就會再次執行以更新其輸出。這可加速開發,因為 (1) 每當您儲存檔案時,就會自動重建,以及 (2) 工作可從記憶體內快取獲益,因為其程序永遠不會終止。

但這些功能通常只適用於單一專案。在單一儲存庫中工作時,我們需要能夠**一次監看多個專案**的監看模式。

一個思考實驗

假設我們的單一儲存庫有下列專案

a sample monorepo

在上圖中,圓圈代表本機專案,而非外部 NPM 相依性。從 DC 的箭頭表示 D 相依於 C;這表示 C 必須先建置,才能建置 D

假設您儲存對專案 B 的變更

rush build --impacted-by B

對於多專案「監看模式」,我們會預期依序發生以下情況

  • B 應該會重建,因為其檔案已變更;
  • 接著,C 應該會重建,因為它相依於 B
  • 接著,D 應該會重建,因為它相依於 C
  • 最後,Webpack 開發伺服器 (假設由 D 主機) 會使用重建的應用程式重新整理您的網頁瀏覽器

如何使用 Rush 完成?假設我們的專案 BC 有如下的簡單建置指令碼

package.json

  . . .
"scripts": {
"build": "rm -Rf lib/ && tsc && jest"
}
. . .

我們可能會嘗試一個實驗,例如在無止盡的迴圈中叫用 rush build --to-except D...

# Build everything that D depends on (but not D itself),
# and keep doing that in an endless loop:
while true; do rush build --to-except D; done

...然後,在執行此動作時,我們會在專案 D 的資料夾中叫用 heft start (或 webpack serve)。

您會發現此方法有一些問題

  • rm -Rf lib/ 會刪除符號連結目標的檔案。符號連結似乎會混淆 Webpack 的檔案監看程式,因此您可能會看到許多錯誤,指出找不到匯入的檔案。Webpack 不會從中復原,因為當檔案稍後被重寫時,符號連結時間戳記不會更新。

  • 在監看時,jestrm -Rf 步驟通常不重要。開發人員的**編輯 -> 重建 -> 重新載入**內部迴圈比它需要的速度慢得多。

這些問題可以藉由為監看模式建立特殊的簡化指令碼來解決,如下所示

package.json

  . . .
"scripts": {
"build": "rm -Rf lib/ && tsc && jest",
"build:watch": "tsc"
}
. . .

「watchForChanges」設定 (實驗性)

Rush 的多專案「監看模式」正式化了這個基本概念,以最佳化的 chokidar 檔案系統監視器取代了簡單迴圈。

如何啟用 Rush 多專案監看模式,取決於您是否對建置指令碼使用批次指令分階段指令。我們建議您在啟用監看模式之前切換到分階段建置,因為它對於開發人員而言是更好且更容易理解的體驗。

分階段指令的監看模式

  1. 在您的 command-line.json 設定檔中,將新的 watchOptions 區段新增至您想要啟用的每個分階段指令。例如

      . . .
    "commands": [
    {
    "commandKind": "phased",
    "name": "build",
    "phases": ["_phase:build"],
    "enableParallelism": true,
    "incremental": true,
    "watchOptions": {
    "alwaysWatch": false,
    "watchPhases": ["_phase:build"]
    }
    },
    {
    "commandKind": "phased",
    "name": "test",
    "phases": ["_phase:build", "_phase:test"],
    "enableParallelism": true,
    "incremental": true,
    "watchOptions": {
    "alwaysWatch": false,
    "watchPhases": ["_phase:build", "_phase:test"]
    }
    }
    ]

    Rush 會自動將新的布林旗標 --watch 新增至具有 watchOptions 屬性的任何指令。

  2. 使用專案選取參數叫用指令,以選取 D 的所有相依性,但不選取 D 本身

    # Build everything that D depends on (but not D itself),
    # and keep doing that in an endless loop:
    $ rush build --watch --to-except D
  3. 然後,在應用程式資料夾中啟動您的開發伺服器

    # Start Webpack's dev server in the folder for project D
    # (which is the web application in this example):
    $ cd apps/D
    $ heft start # <-- or your own "npm run start" equivalent here

批次指令的監看模式

  1. 在您的 command-line.json 設定檔中新增自訂指令。繼續上述範例,我們的自訂指令會稱為 "build:watch"。重要的設定是 "incremental""watchForChanges"

    common/config/rush/command-line.json

      . . .
    "commands": [
    {
    "name": "build:watch",
    "commandKind": "bulk",
    "summary": "Build projects and watch for changes",
    "description": "For details, see the article \"Using watch mode\" on the Rush website: https://rush.dev.org.tw/",

    // use incremental build logic (important)
    "incremental": true,
    "enableParallelism": true,
    // Enable "watch mode"
    "watchForChanges": true
    },
    . . .
  2. "build:watch" 指令碼新增至每個 Rush 專案的 package.json 檔案。(PR #2298 旨在為 "build:watch""build" 相同的專案簡化此步驟。最終也可以將這些定義合併在共用的 rig 套件中。)

    如果您使用 Heft,您的指令碼看起來會像這樣

    package.json

      . . .
    "scripts": {
    "build": "heft build --clean",
    "build:watch": "heft build"
    }
    . . .
  3. 使用專案選取參數叫用指令,以選取 D 的所有相依性,但不選取 D 本身

    # Build everything that D depends on (but not D itself),
    # and keep doing that in an endless loop:
    rush build:watch --to-except D
  4. 最後,在應用程式資料夾中啟動您的開發伺服器

    # Start Webpack's dev server in the folder for project D
    # (which is the web application in this example):
    cd apps/D
    heft start # <-- or your own "npm run start" equivalent here
  5. 在某些情況下,--changed-projects-only 指令可以與 "watchForChanges" 結合,以實現更快的監看。<僅建置已變更的專案>一節說明了它的運作方式以及何時適用。

「實驗性」 "watchForChanges" 功能仍處於早期階段。歡迎提供意見反應!GitHub 問題 #1202 追蹤其他工作項目和 William Bernting 的原始開發計畫。

社群解決方案

Rush 社群分享了一些有趣的替代方法來解決這個問題,這些方法也很有幫助

  • @telia/rush-select 是一個互動式儀表板,用於監看 Rush 專案和選取要重建的專案。

  • rush-dev-watcherDaniel Imfeld 提供的一個簡單但實用的指令碼,可執行初始建置,然後啟動多個監看程式。

另請參閱