Skip to content
This repository has been archived by the owner on Apr 8, 2020. It is now read-only.

UseProxyToSpaDevelopmentServer doesn't auto-refresh browser using an Aurelia ClientApp with HMR #1743

Closed
chrisckc opened this issue Aug 21, 2018 · 3 comments

Comments

@chrisckc
Copy link

chrisckc commented Aug 21, 2018

I created a project using the latest dotnet new angular template and replaced the ClientApp folder with an Aurelia app created using the Aurelia CLI.
The command
au new
was ran inside the project folder to create a new ClientApp folder, the following options were used:
Name: ClientApp
Platform: Web
Bundler: Webpack

Startup.cs was modified to use spa.UseProxyToSpaDevelopmentServer:
//spa.UseAngularCliServer(npmScript: "start");
spa.UseProxyToSpaDevelopmentServer(baseUri: "http://localhost:8080");

When i run both
au run --watch
and
dotnet run
it works fine, i can edit a file in the Aurelia app and the browser refreshes automatically using a full page refresh.

However if i run
au run --watch --hmr
instead, the auto refresh no longer works, but still works if i visit the Aurelia app directly via http://localhost:8080 (still refreshes the whole page as there is only 1 module in the au new template) it just no longer works from the dotnet host on http://localhost:5000 or https://localhost:5001

I then checked to see if "Hot Module Replacement" worked in the Angular app which was created by the template by enabling it using the following guide:
https://github.com/angular/angular-cli/wiki/1-x-stories-configure-hmr
and edited startup.cs to use the angular url:
spa.UseProxyToSpaDevelopmentServer(baseUri: "http://localhost:4200");
It works fine, i can edit a file in the angular project and see that the page updates without a full page refresh.

I have not read enough about HMR to understand how it does what it does, but as both ClientApps are using Webpack hmr, i would have expected it to also work in Aurelia through the spa proxy.

@chrisckc chrisckc changed the title hmr UseProxyToSpaDevelopmentServer doesn't auto-refresh browser using an Aurelia ClientApp with HMR Aug 21, 2018
@chrisckc chrisckc reopened this Aug 21, 2018
@chrisckc
Copy link
Author

chrisckc commented Oct 31, 2018

Just an update on this, checking the Chrome console log, this error can be seen when using hmr with my Aurelia ClientApp as described above:

GET https://localhost:8080/sockjs-node/info?t=1540995938707 net::ERR_CONNECTION_CLOSED

The above request should be going via the dotnet host rather than directly to the webpack server.

I have now compared this to what happens in the Angular Spa template, it seems when using Angular as the ClientApp, the request is correctly sent to:

https://localhost:5001/sockjs-node/info?t=1540996146714

For some reason, in the Aurelia Template i created the request is being sent directly to the webpack dev server rather than to the dotnet host to be proxied through to the dev server. This in theory should still work, but fails because the dev server is not running on https, only the dotnet host.

So it works in the Angular Spa template, I am not sure what magic is happening behind the scenes in the Angular CLI when i run npm run hmr which in turn runs the CLI with ng serve --hmr -e=hmr

There must be some magic because if i run ng eject which "ejects" us from the friendly and magic world of the Angular CLI and generates the required webpack config, it breaks.

Once ejected from the CLI, running npm run hmr which in now runs webpack directly with webpack-dev-server --port=4200 --hot (after editing the package.json) we see the following error:

GET https://localhost:4200/sockjs-node/info?t=1540997851706 net::ERR_CONNECTION_CLOSED

That is the same issue as what i am seeing with the Aurelia ClientApp. Ejecting from the CLI is a likely scenario for many Angular projects, at which point HMR will no longer work it seems. To complicate things further, when accessing Angular directly via "http://localhost:4200/" after ejecting, although there are no errors when requesting "/sockjs-node/", HMR is now not working properly as the whole page now refreshes when doing the same edit that previously caused a partial page refresh.

The Aurelia ClientApp always works with HMR when accessing it directly.

I haven't tried different versions of webpack-dev-server as yet, the versions are different between the Angular and Aurelia ClientApp's but the behaviour is the same once ejected from the Angular CLI.

Does anyone happen to know what magic is happening in the Angular CLI that makes this work?

@chrisckc
Copy link
Author

chrisckc commented Oct 31, 2018

Ok, i tried to figure what what was causing the websocket redirect to port 8080 from 5001 and spotted this:
Inside "ClientApp/aurelia_project/tasks/run.ts" there is a line which updates a copy of the webpack config used when running the app:

config.entry.app.unshift(`webpack-dev-server/client?http://${opts.host}:${opts.port}/`, 'webpack/hot/dev-server');

changing this to point to https://${opts.host}:5001/ solves the problem, that is not ideal because it will break when accessing the dev server directly.

Luckily the address is not required, it also works fine using this:

config.entry.app.unshift(`webpack-dev-server/client`, 'webpack/hot/dev-server');

Solved! my Aurelia ClientApp now works correctly with HMR either through https://localhost:5001 or http://localhost:8080 or any other address it is made to run on.

So not a JavaScriptServices issue, however anyone using Angular and ejecting from the Angular CLI will break HMR which may be relevant under this repo due to the Angular SPA template.
Closing this.

@chrisckc
Copy link
Author

chrisckc commented Nov 6, 2018

Update: If you try to run Aurelia from a subpath for example by setting const baseUrl = '/app/'; in the webpack config, which sets output.publicPath you need to use this format in run.ts to set the client path to '/'

config.entry.app.unshift(`webpack-dev-server/client?/`, 'webpack/hot/dev-server');

It seems that the path used by the dev server client to access the websocket server is inherited from the publicPath setting or derived some other variable generated from that . Currently the dev server websocket is not able to listen on a subpath until this is done:
webpack/webpack-dev-server#1553
so the client must be forced back to using '/' as the path

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant