Développer des applications ASP.NET Core à l’aide d’un observateur de fichiers

Par Rick Anderson et Victor Hurdugaci

dotnet watch est un outil qui exécute une commande CLI .NET lorsque les fichiers source sont modifiés. Par exemple, un changement de fichier peut déclencher la compilation, l’exécution de tests ou le déploiement.

Ce tutoriel utilise une API web existante avec deux points de terminaison : un qui retourne une somme et un qui retourne un produit. La méthode du produit comporte un bogue, qui est résolu dans ce tutoriel.

Téléchargez l’application exemple. Elle se compose de deux projets : WebApp (API web ASP.NET Core) et WebAppTests (API de tests unitaires pour le web).

Dans une interface de commande, accédez au dossier WebApp. Exécutez la commande suivante :

dotnet run

Notes

Vous pouvez utiliser dotnet run --project <PROJECT> pour spécifier un projet à exécuter. Par exemple, dotnet run --project WebApp à la racine de l’exemple d’application aura également pour effet d’exécuter le projet WebApp.

La sortie de la console affiche des messages semblables à ce qui suit (indiquant que l’application est en cours d’exécution et en attente de demandes) :

$ 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.

Dans un navigateur web, accédez à http://localhost:<port number>/api/math/sum?a=4&b=5. Vous devez voir le résultat 9.

Accédez à l’API du produit (http://localhost:<port number>/api/math/product?a=4&b=5). Elle retourne 9, et non pas 20 comme prévu. Ce problème est résolu plus tard dans le tutoriel.

Ajouter dotnet watch à un projet

L’outil Observateur de fichiers dotnet watch est inclus dans la version 2.1.300 du kit SDK .NET Core. Les étapes suivantes sont requises quand vous utilisez une version antérieure du kit SDK .NET Core.

  1. Ajoutez une référence au package Microsoft.DotNet.Watcher.Tools au fichier .csproj :

    <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
    </ItemGroup>
    
  2. Installez le package Microsoft.DotNet.Watcher.Tools en exécutant la commande suivante :

    dotnet restore
    

Exécuter les commandes de l’interface CLI de .NET avec dotnet watch

Toutes les commandes de l’interface CLI de .NET peuvent être exécutées avec dotnet watch. Par exemple :

Commande Commande avec watch
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

Exécutez dotnet watch run dans le dossier WebApp. La sortie de la console indique que watch a démarré.

L’exécution de dotnet watch run sur une application web lance un navigateur qui accède à l’URL de l’application une fois celle-ci prête. dotnet watch effectue cette opération en lisant la sortie de la console de l’application et en attendant le message Prêt affiché par WebHost.

dotnet watch actualise le navigateur lorsqu’il détecte des modifications apportées aux fichiers surveillés. Pour ce faire, la commande watch injecte un intergiciel dans l’application qui modifie les réponses HTML créées par l’application. L’intergiciel ajoute un bloc de script JavaScript à la page qui permet à dotnet watch d’indiquer au navigateur qu’il doit s’actualiser. Actuellement, les modifications apportées à tous les fichiers surveillés, y compris le contenu statique, comme les fichiers .html et .css, entraînent la reconstruction de l’application.

dotnet watch:

  • Surveille uniquement les fichiers qui ont un impact sur les builds par défaut.
  • Tous les fichiers surveillés supplémentaires (via la configuration) entraînent toujours une génération.

Pour plus d’informations sur la configuration, consultez Configuration de dotnet-watch dans ce document.

Notes

Vous pouvez utiliser dotnet watch --project <PROJECT> pour spécifier un projet à surveiller. Par exemple, dotnet watch --project WebApp run à la racine de l’exemple d’application aura également pour effet d’exécuter le projet WebApp et d’en effectuer le suivi.

Apporter des modifications avec dotnet watch

Vérifiez que dotnet watch est en cours d’exécution.

Corrigez le bogue présent dans la méthode Product de MathController.cs afin qu’elle retourne le produit et non la somme :

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

Enregistrez le fichier . La sortie de la console indique que dotnet watch a détecté un changement de fichier et a redémarré l’application.

Vérifiez que http://localhost:<port number>/api/math/product?a=4&b=5 retourne le résultat correct.

Exécuter les tests à l’aide de dotnet watch

  1. Changez la méthode Product de MathController.cs pour qu’elle retourne à nouveau la somme. Enregistrez le fichier .

  2. Dans une interface de commande, accédez au dossier WebAppTests.

  3. Exécutez dotnet restore.

  4. Exécutez dotnet watch test. Sa sortie indique qu’un test a échoué et que l’observateur est en attente de changement de fichier :

    Total tests: 2. Passed: 1. Failed: 1. Skipped: 0.
    Test Run Failed.
    
  5. Corrigez le code de la méthode Product afin qu’elle retourne le produit. Enregistrez le fichier .

dotnet watch détecte le changement de fichier et réexécute les tests. La sortie de la console indique que les tests ont réussi.

Personnaliser la liste de fichiers à observer

Par défaut, dotnet-watch effectue le suivi de tous les fichiers qui correspondent aux modèles Glob suivants :

  • **/*.cs
  • *.csproj
  • **/*.resx
  • Fichiers de contenu : wwwroot/**, **/*.config, **/*.json

Vous pouvez ajouter plusieurs éléments à la liste de suivi en modifiant le fichier .csproj. Vous pouvez spécifier des éléments individuellement ou en utilisant des modèles Glob.

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

Exclusion de fichiers à observer

dotnet-watch peut être configuré pour ignorer ses paramètres par défaut. Pour ignorer des fichiers spécifiques, ajoutez l’attribut Watch="false" à la définition d’un élément dans le fichier .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>

Personnaliser les projets de suivi

dotnet-watch n’est pas limité aux projets C#. Vous pouvez créer des projets de suivi personnalisés pour gérer différents scénarios. Considérez l’organisation de projets suivante :

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

Si l’objectif est d’observer les deux projets, créez un fichier projet personnalisé configuré à cette fin :

<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>

Pour démarrer l’observation de fichiers sur les deux projets, passez au dossier test. Exécutez la commande suivante :

dotnet watch msbuild /t:Test

VSTest s’exécute quand n’importe quel fichier change dans un des projets de test.

Configuration de dotnet-watch

Certaines options de configuration peuvent être transmises à dotnet watch via des variables d’environnement. Les variables disponibles sont les suivantes :

Paramètre Description
DOTNET_USE_POLLING_FILE_WATCHER Si la valeur est « 1 » ou « true », dotnet watch utilise un observateur de fichiers d’interrogation au lieu du FileSystemWatcher de CoreFx. Utilisé lors de la surveillance de fichiers sur des partages réseau ou des volumes montés par Docker.
DOTNET_WATCH_SUPPRESS_MSBUILD_INCREMENTALISM Par défaut, dotnet watch optimise la génération en évitant certaines opérations, comme l’exécution d’une restauration ou la réévaluation de l’ensemble des fichiers observés à chaque modification de fichier. Si la valeur est « 1 » ou « true », ces optimisations sont désactivées.
DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER dotnet watch run tente de lancer des navigateurs pour les applications web avec launchBrowser configuré dans launchSettings.json. Si la valeur est « 1 » ou « true », ce comportement est supprimé.
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH dotnet watch run tente d’actualiser les navigateurs lorsqu’il détecte des modifications de fichier. Si la valeur est « 1 » ou « true », ce comportement est supprimé. Ce comportement est également supprimé si DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER est défini.

Actualisation du navigateur

dotnet watch injecte un script dans l’application qui lui permet d’actualiser le navigateur lorsque le contenu change. Dans certains scénarios, par exemple lorsque l’application active la compression de réponse, dotnet watch peut ne pas être en mesure d’injecter le script. Dans de tels cas lors du développement, injectez manuellement le script dans l’application. Par exemple, pour configurer l’application web pour injecter manuellement le script, mettez à jour le fichier de disposition pour inclure _framework/aspnet-browser-refresh.js :

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

Caractères non-ASCII

Visual Studio 17.2 et versions ultérieures incluent le SDK .NET 6.0.300 et versions ultérieures. Avec le SDK .NET et la version 6.0.300 ou ultérieure, dotnet-watch émet des caractères non ASCII vers la console pendant une session de rechargement à chaud. Sur certains hôtes de console, comme le conhost Windows, ces caractères peuvent apparaître brouillés. Pour éviter les caractères brouillés, envisagez l’une des approches suivantes :

  • Configurez la variable d’environnement DOTNET_WATCH_SUPPRESS_EMOJIS=1 pour supprimer l’émission de ces valeurs.
  • Basculez vers un autre terminal, comme https://github.com/microsoft/terminal, qui prend en charge le rendu des caractères non ASCII.