使用檔案監看員開發 ASP.NET Core 應用程式

作者:Rick AndersonVictor Hurdugaci

dotnet watch 是一種工具,會在來源檔案變更時執行 .NET Core CLI 命令。 例如,檔案變更會觸發編譯、測試執行或部署。

本教學課程使用現有的 Web API 與兩個端點:一個傳回加總,另一個傳回產品。 本教學課程已修正產品方法的 Bug。

下載範例應用程式。 它包含兩個專案:WebApp (ASP.NET Core Web API) 和 WebAppTests (Web API 的單元測試)。

在命令殼層中,巡覽至 WebApp 資料夾。 執行下列命令:

dotnet run

注意

您可以使用 dotnet run --project <PROJECT> 來指定要執行的專案。 例如,從範例應用程式的根目錄執行 dotnet run --project WebApp 同時也會執行 WebApp 專案。

主控台輸出會顯示類似如下的訊息 (指出應用程式正在執行,並等待要求):

$ dotnet run
Hosting environment: Development
Content root path: C:/Docs/aspnetcore/tutorials/dotnet-watch/sample/WebApp
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

在網頁瀏覽器中,巡覽至 http://localhost:<port number>/api/math/sum?a=4&b=5。 您應該會看到 9 的結果。

瀏覽至產品 API (http://localhost:<port number>/api/math/product?a=4&b=5)。 它會傳回 9,而非您預期的 20。 本教學課程稍後會修正該問題。

dotnet watch 新增至專案

dotnet watch 檔案監看員工具隨附於 .NET Core SDK 2.1.300 版本。 使用舊版的 .NET Core SDK 需要以下的步驟。

  1. Microsoft.DotNet.Watcher.Tools 套件參考新增至 .csproj 檔案:

    <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
    </ItemGroup>
    
  2. 執行下列命令來安裝 Microsoft.DotNet.Watcher.Tools 套件:

    dotnet restore
    

使用 dotnet watch 執行 .NET Core CLI 命令

任何 .NET Core CLI 命令都可以使用 dotnet watch 執行。 例如:

Command 使用監看式的命令
dotnet run dotnet watch run
dotnet run -f netcoreapp3.1 dotnet watch run -f netcoreapp3.1
dotnet run -f netcoreapp3.1 -- --arg1 dotnet watch run -f netcoreapp3.1 -- --arg1
dotnet test dotnet watch test

執行 WebApp 資料夾中的 dotnet watch run。 主控台輸出指出 watch 已啟動。

在 Web 應用程式上執行 dotnet watch run 會啟動瀏覽器,一旦準備就緒,就會巡覽至應用程式的 URL。 dotnet watch 是透過讀取應用程式的主控台輸出,並等候 WebHost 顯示就緒訊息來完成此操作。

dotnet watch 偵測到所監看的檔案發生變更時,會重新整理瀏覽器。 為此,Watch 命令會將中介軟體插入應用程式,以修改應用程式所建立的 HTML 回應。 中介軟體會在頁面上新增 JavaScript 指令碼區塊,以允許 dotnet watch 指示瀏覽器進行重新整理。 目前,對所有受監看檔案的變更,包括諸如 .html.css 檔案等靜態內容,都會導致重建應用程式。

dotnet watch

  • 預設僅監看會影響建置的檔案。
  • 任何額外的受監看檔案 (透過組態) 仍然會導致組建發生。

如需組態的詳細資訊,請參閱此文件中的 dotnet-watch 組態

注意

您可以使用 dotnet watch --project <PROJECT> 來指定要監看的專案。 例如,從範例應用程式的根目錄執行 dotnet watch --project WebApp run 同時也會執行並監看 WebApp 專案。

dotnet watch 進行變更

請確認 dotnet watch 正在執行。

修正 MathController.csProduct 方法的 Bug,使其傳回產品而非總和:

public static int Product(int a, int b)
{
    return a * b;
}

儲存檔案。 主控台輸出指出 dotnet watch 已偵測到檔案變更,並重新啟動應用程式。

驗證 http://localhost:<port number>/api/math/product?a=4&b=5 是否傳回正確的結果。

使用 dotnet watch 執行測試

  1. MathController.csProduct 方法變更回傳回總和。 儲存檔案。

  2. 在命令殼層中,瀏覽至 WebAppTests 資料夾。

  3. 執行 dotnet restore

  4. 執行 dotnet watch test。 其輸出指出測試失敗,且監看員正在等候檔案變更:

    Total tests: 2. Passed: 1. Failed: 1. Skipped: 0.
    Test Run Failed.
    
  5. 修正 Product 方法程式碼,使其傳回產品。 儲存檔案。

dotnet watch 會偵測檔案變更,並重新執行測試。 主控台輸出指出測試成功。

自訂要監看的檔案清單

根據預設,dotnet-watch 會追蹤符合下列 Glob 模式的所有檔案:

  • **/*.cs
  • *.csproj
  • **/*.resx
  • 內容檔:wwwroot/****/*.config**/*.json

編輯 .csproj 檔案可將更多項目新增至監看清單。 項目可以個別或使用 Glob 模式指定。

<ItemGroup>
    <!-- extends watching group to include *.js files -->
    <Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
</ItemGroup>

選擇不使用要監看的檔案

dotnet-watch 可以設定成忽略其預設設定。 若要忽略特定的檔案,請將 Watch="false" 屬性新增至 .csproj 檔案的項目定義中:

<ItemGroup>
    <!-- exclude Generated.cs from dotnet-watch -->
    <Compile Include="Generated.cs" Watch="false" />

    <!-- exclude Strings.resx from dotnet-watch -->
    <EmbeddedResource Include="Strings.resx" Watch="false" />

    <!-- exclude changes in this referenced project -->
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" Watch="false" />
</ItemGroup>
<ItemGroup>
     <!-- Exclude all Content items from being watched. -->
    <Content Update="@(Content)" Watch="false" />
</ItemGroup>

自訂監看式專案

dotnet-watch 不限制為 C# 專案。 您可以建立自訂的監看式專案來處理不同的案例。 請考慮下列專案配置:

  • test/
    • UnitTests/UnitTests.csproj
    • IntegrationTests/IntegrationTests.csproj

如果目標是監看這兩個專案,請建立設定成監看這兩個專案的自訂專案檔:

<Project>
    <ItemGroup>
        <TestProjects Include="**\*.csproj" />
        <Watch Include="**\*.cs" />
    </ItemGroup>

    <Target Name="Test">
        <MSBuild Targets="VSTest" Projects="@(TestProjects)" />
    </Target>

    <Import Project="$(MSBuildExtensionsPath)\Microsoft.Common.targets" />
</Project>

若要開始監看兩個專案的檔案,請變更至 test 資料夾。 執行以下 命令:

dotnet watch msbuild /t:Test

任一測試專案中的任何檔案發生變更時,就會執行 VSTest。

dotnet-watch 組態

某些組態選項可以透過環境變數傳遞至 dotnet watch。 可用的變數有:

設定 描述
DOTNET_USE_POLLING_FILE_WATCHER 如果設定為「1」或「true」,dotnet watch 會使用輪詢檔案監看員,而不是 CoreFx 的 FileSystemWatcher。 於監看網路共用或 Docker 裝載的磁碟區的檔案時使用。
DOTNET_WATCH_SUPPRESS_MSBUILD_INCREMENTALISM 根據預設,dotnet watch 會避免執行還原或重新評估每個檔案變更上的受監看檔案等特定作業,藉此最佳化建置程式。 如果設定為「1」或「true」,則會停用這些最佳化。
DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER dotnet watch run 嘗試針對在 launchSettings.json 中設定了 launchBrowser 的 Web 應用程式啟動瀏覽器。 如果設定為「1」或「true」,則會抑制此行為。
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH dotnet watch run 嘗試在偵測到檔案變更時重新整理瀏覽器。 如果設定為「1」或「true」,則會抑制此行為。 如果 DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER 已設定,也會抑制此行為。

瀏覽器重新整理

dotnet watch 會將指令碼插入應用程式,以在內容變更時重新整理瀏覽器。 在某些情況下,例如當應用程式啟用回應壓縮時,dotnet watch 可能無法插入指令碼。 開發中出現此類情況時,請手動將指令碼插入到應用程式中。 例如,若要將 Web 應用程式設定為手動插入指令碼,請更新配置檔案以包含 _framework/aspnet-browser-refresh.js

@* _Layout.cshtml *@
<environment names="Development">
    <script src="/_framework/aspnetcore-browser-refresh.js"></script>
</environment>

非 ASCII 字元

Visual Studio 17.2 和更新版本內含 .NET SDK 6.0.300 和更新版本。 透過 .NET SDK 和 6.0.300 更新版本,dotnet-watch 可在熱重載工作階段,向主控台發出非 ASCII 字元。 在特定的主控台主機上,例如 Windows conhost,此類字元可能會顯示為亂碼。 為避免出現亂碼字元,請考慮下列其中一種方法:

  • 設定 DOTNET_WATCH_SUPPRESS_EMOJIS=1 環境變數以抑制發出這些值。
  • 切換至支援轉譯非 ASCII 字元的不同終端機,例如 https://github.com/microsoft/terminal