Desarrollar aplicaciones ASP.NET Core con un monitor de archivos
Por Rick Anderson y Victor Hurdugaci
dotnet watch
es una herramienta que ejecuta un comando de la CLI de .NET cuando se modifican los archivos de código fuente. Por ejemplo, un cambio en un archivo puede desencadenar una compilación, una ejecución de prueba o una implementación.
En este tutorial usaremos una API web existente con dos puntos de conexión: uno que devuelve una suma y otro que devuelve un producto. El método Product contiene un error, que se ha corregido en este tutorial.
Descargue la aplicación de ejemplo. Consta de dos proyectos: WebApp (API web de ASP.NET Core) y WebAppTests (pruebas unitarias para la API web).
En un shell de comandos, desplácese hasta la carpeta WebApp. Ejecute el siguiente comando:
dotnet run
Nota
Puede usar dotnet run --project <PROJECT>
para especificar un proyecto para que se ejecute. Por ejemplo, al ejecutar dotnet run --project WebApp
desde la raíz de la aplicación de ejemplo, también se ejecutará el proyecto WebApp.
La salida de la consola muestra mensajes similares al siguiente (indicando que la aplicación se ejecuta y espera solicitudes):
$ 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.
En un explorador web, vaya a http://localhost:<port number>/api/math/sum?a=4&b=5
. Debería ver el resultado de 9
.
Navegue a la API del producto (http://localhost:<port number>/api/math/product?a=4&b=5
). Devuelve 9
, no 20
tal como se esperaría. Ese problema se corregirá más adelante en el tutorial.
Agregar dotnet watch
a un proyecto
La herramienta de monitor de archivos dotnet watch
se incluye con la versión 2.1.300 del SDK de .NET Core. Si se usa una versión anterior del SDK de .NET Core, será necesario realizar los siguientes pasos.
Agregue una referencia de paquete
Microsoft.DotNet.Watcher.Tools
al archivo.csproj
:<ItemGroup> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" /> </ItemGroup>
Instale el paquete
Microsoft.DotNet.Watcher.Tools
mediante la ejecución del comando siguiente:dotnet restore
Ejecutar los comandos de la CLI de .NET con dotnet watch
Cualquier comando de la CLI de .NET se puede ejecutar con dotnet watch
. Por ejemplo:
Comando | Comando con 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 |
Ejecute dotnet watch run
en la carpeta WebApp. La salida de la consola indica que se ha iniciado watch
.
La ejecución de dotnet watch run
en una aplicación web inicia un explorador que navega a la dirección URL de la aplicación una vez lista. Para ello, dotnet watch
lee la salida de la consola de la aplicación y espera el mensaje de preparado que WebHost muestra.
dotnet watch
actualiza el explorador cuando detecta cambios en los archivos inspeccionados. Para ello, el comando watch inserta un middleware en la aplicación que modifica las respuestas HTML creadas por la aplicación. El middleware agrega un bloque de script de JavaScript a la página que permite a dotnet watch
indicar al explorador que actualice. Actualmente, los cambios en todos los archivos inspeccionados, que incluye contenido estático como los archivos .html
y .css
, hacen que la aplicación se vuelva a generar.
dotnet watch
:
- Solo inspecciona los archivos que afectan a las compilaciones de forma predeterminada.
- Los archivos inspeccionados adicionalmente (a través de la configuración) siguen generando una compilación.
Para obtener más información sobre la configuración, consulte configuración de dotnet-watch en este documento.
Nota
Puede usar dotnet watch --project <PROJECT>
para especificar un proyecto para verlo. Por ejemplo, al ejecutar dotnet watch --project WebApp run
desde la raíz de la aplicación de ejemplo, también se ejecutará y se verá el proyecto WebApp.
Realizar cambios con dotnet watch
Asegúrese de que dotnet watch
se está ejecutando.
Corrija el error del método Product
de MathController.cs
para que devuelva el producto y no la suma:
public static int Product(int a, int b)
{
return a * b;
}
Guarde el archivo. La salida de la consola muestra que dotnet watch
ha detectado un cambio de archivo y ha reiniciado la aplicación.
Compruebe que http://localhost:<port number>/api/math/product?a=4&b=5
devuelve el resultado correcto.
Ejecutar pruebas con dotnet watch
Vuelva a cambiar el método
Product
deMathController.cs
para devolver la suma. Guarde el archivo.En un shell de comandos, desplácese hasta la carpeta WebAppTests.
Ejecute dotnet restore.
Ejecute
dotnet watch test
. La salida que indica que se ha producido un error en una prueba y que el monitor espera cambios de archivos:Total tests: 2. Passed: 1. Failed: 1. Skipped: 0. Test Run Failed.
Corrija el código del método
Product
para que devuelva el producto. Guarde el archivo.
dotnet watch
detecta el cambio de archivo y vuelve a ejecutar las pruebas. La salida de la consola indica que se han superado las pruebas.
Personalizar la lista de archivos que inspeccionar
dotnet-watch
realiza un seguimiento de forma predeterminada de todos los archivos que coincidan con los siguientes patrones globales:
**/*.cs
*.csproj
**/*.resx
- Archivos de contenido:
wwwroot/**
,**/*.config
y**/*.json
Se pueden agregar más elementos a la lista de control inspección editando el archivo .csproj
. Los elementos se pueden especificar individualmente o usando patrones globales.
<ItemGroup>
<!-- extends watching group to include *.js files -->
<Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
</ItemGroup>
Descartar archivos de la inspección
dotnet-watch
se puede configurar para pasar por alto su configuración predeterminada. Para omitir archivos concretos, agregue el atributo Watch="false"
a la definición de un elemento en el archivo .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>
Proyectos de inspección personalizados
dotnet-watch
no queda restringido exclusivamente a proyectos de C#, sino que se pueden crear proyectos de inspección personalizados para controlar distintos escenarios. Veamos el siguiente diseño de proyecto:
- test/
UnitTests/UnitTests.csproj
IntegrationTests/IntegrationTests.csproj
Si el objetivo es inspeccionar los dos proyectos, cree un archivo de proyecto personalizado configurado para supervisar ambos proyectos:
<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>
Para empezar a inspeccionar archivos en ambos proyectos, cambie a la carpeta test. Ejecute el siguiente comando:
dotnet watch msbuild /t:Test
VSTest se ejecuta cuando un archivo de cualquiera de los proyectos de prueba cambie.
configuración de dotnet-watch
Algunas opciones de configuración se pueden pasar a dotnet watch
a través de variables de entorno. Las variables disponibles son:
Parámetro | Descripción |
---|---|
DOTNET_USE_POLLING_FILE_WATCHER |
Si se establece en "1" o "true", dotnet watch usa un monitor de archivo de sondeo en lugar de FileSystemWatcher de CoreFx. Se usa al inspeccionar archivos en recursos compartidos de red o volúmenes montados de Docker. |
DOTNET_WATCH_SUPPRESS_MSBUILD_INCREMENTALISM |
De forma predeterminada, dotnet watch optimiza la compilación evitando ciertas operaciones, como ejecutar la restauración o volver a evaluar el conjunto de archivos inspeccionados en cada cambio de archivo. Si se establece en "1" o "true", estas optimizaciones se deshabilitan. |
DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER |
dotnet watch run intenta iniciar los exploradores para aplicaciones web con launchBrowser configurado en launchSettings.json . Si se establece en "1" o "true", se suprime este comportamiento. |
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH |
dotnet watch run intenta actualizar los exploradores cuando detecta cambios en los archivos. Si se establece en "1" o "true", se suprime este comportamiento. Este comportamiento también se suprime si se establece DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER . |
Actualización del explorador
dotnet watch
inserta un script en la aplicación que le permite actualizar el explorador cuando cambia el contenido. En algunos escenarios, como cuando la aplicación habilita la compresión de respuesta, es posible que dotnet watch
no pueda insertar el script. En estos casos de desarrollo, inserte de forma manual el script en la aplicación. Por ejemplo, a fin de configurar la aplicación web para insertar manualmente el script, actualice el archivo de diseño para incluir _framework/aspnet-browser-refresh.js
:
@* _Layout.cshtml *@
<environment names="Development">
<script src="/_framework/aspnetcore-browser-refresh.js"></script>
</environment>
Caracteres que no son ASCII
En Visual Studio 17.2 y versiones posteriores se incluye el SDK de .NET 6.0.300 y posterior. Con el SDK de .NET 6.0.300 y posteriores, dotnet-watch
emite caracteres que no son ASCII a la consola durante una sesión de recarga activa. En determinados hosts de consola, como conhost de Windows, estos caracteres pueden parecer indescifrables. Para evitar caracteres indescifrables, considere uno de los enfoques siguientes:
- Configure la variable de entorno
DOTNET_WATCH_SUPPRESS_EMOJIS=1
para suprimir la emisión de estos valores. - Cambie a otro terminal, como https://github.com/microsoft/terminal, que admite la representación de caracteres no ASCII.