1

So I was watching a channel 9 video on Angular CLI with .Net Core here: https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Angular-and-NET-Core

At position 8:15 he demos auto-syncing where updating a .ts file in the Angular CLI folder compiled on save, then later caused the view to update. I tried this an it does not update at all (unless I refresh the whole page).

I also noticed that the template does not work out of the box (big surprise). I managed to update it to the newer Angular version (and ran into an error where the template had incorrectly created "start": "ng serve --extract-css", to package.json where --extract-css is invalid and had to remove it). I also assumed that Visual Studio (2017) would compile Angular on its own, but it did not, so I added this to the project file:

  <Target Name="NgDebug" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">
    <!--Run Angular build in debug mode (NOTE: does not support symbolic links nor junction points)-->
    <Message Importance="high" Text="Building the Angular code in debug (dev) mode ..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="ng build" />
  </Target>

  <Target Name="NgRelease" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Release' ">
    <!--Run Angular build in prod mode (NOTE: does not support symbolic links nor junction points)-->
    <Message Importance="high" Text="Building the Angular code in release (prod) mode ..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="ng build --prod" />
  </Target>

Two questions here:

  1. Is this sync feature expected to work today? Is there a configuration required?
  2. Am I expected to setup the ng build step myself, or is there a different method I should be using for the ASP.Net Core (with Angular CLI) template?

Here is the app.UseSpa code:

    app.UseSpa(spa =>
    {
        // To learn more about options for serving an Angular SPA from ASP.NET Core,
        // see https://go.microsoft.com/fwlink/?linkid=864501

        spa.Options.SourcePath = "ClientApp";

        if (env.IsDevelopment())
        {
            spa.UseAngularCliServer(npmScript: "start");
        }
    });
James Wilkins
  • 6,836
  • 3
  • 48
  • 73

1 Answers1

2

So it appears the correct terminology is "Hot Module Replacement" (MHR - AKA "Live Reloading", or "Hot Updates/Reloading"). Following this answer got me part way there:

https://stackoverflow.com/a/50934814/1236397

The part missing was found here: https://github.com/aspnet/JavaScriptServices/issues/1654#issuecomment-430053872

Both of these links seem to suggest that the template Visual Studio creates is ready for production and not development. The two issues are:

  1. The ClientApp\dist folder may get created at some point if you build outside Visual Studio. The existence of the manually created dist folder will break the live reloading. This folder must be deleted entirely.
  2. The VS ASP.Net Core Angular CLI template is ready to serve static files in production mode. The template creator failed to wrap sections to prevent loading in dev mode.

For #2 change these lines:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

...

public IConfiguration Configuration { get; }

...

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/dist";
    });
    ...
}

...

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.UseSpaStaticFiles();
    ...
}

to this:

public Startup(IHostingEnvironment env, IConfiguration configuration)
{
    HostingEnvironment = env;
    Configuration = configuration;
}

...

public IHostingEnvironment HostingEnvironment { get; private set; }
public IConfiguration Configuration { get; }

...

public void ConfigureServices(IServiceCollection services)
{
    ...
    if (HostingEnvironment.IsProduction())
    {
        // In production, the Angular files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });
    }
    ...
}

...

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    if (env.IsProduction())
    {
        app.UseSpaStaticFiles();
    }
    ...
}

However, at this point the pages refresh in full. This is because HMR is not enabled by default. You'll have to follow the proper documentation here:

https://github.com/angular/angular-cli/wiki/stories-configure-hmr

If the link ever goes down, simply search for the documentation using the query configure HMR for angular CLI.

Tip: If you need IE9-11 support, take a look at the polyfills.ts file, and ignore the import 'classlist.js' line, unless you need it (otherwise run npm install --save classlist.js).

James Wilkins
  • 6,836
  • 3
  • 48
  • 73