alpitg / .NetCoreSpa

Hosting two angular app behind .net core 2.2 (Production ready, tested on linux environment)
10 stars 3 forks source link

Live reloading broken after changes (plus solution) #32

Open ttutisani opened 3 years ago

ttutisani commented 3 years ago

Hey, nice work with the project! It helped me have multiple angular client apps under a single .net core web app.

However, after I applied the changes, the live reloading was broken because it tries to listen to the base URL (/) and not the new subdirectories under which you store the client apps (/ClientApp1 or /ClientApp2). This issue can be identified by seeing this error in the Chrome console:

GET http://localhost:port/sockjs-node/info?t=1540568455931 404 (Not Found)

And here is the solution: modify the angular.json file and add the publicHost option under the serve element, like shown below:

serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "options": {
    "browserTarget": "ClientApp1:build",
    "publicHost": "/ClientApp1/"
  }
}

This example assumes that the subdirectory name is ClientApp1. This should fix the live reloading.

Sorry, I don't have time to open a PR with this change, but I thought I could help somebody and payback for your nice work!

Thank you!

alkoval commented 1 year ago

@ttutisani hello, i have similar problem when i try to create app with multiple angular apps. But you recommend is not working. If add --live-reload=false I don't have this problem, but I need to reload the project manually after the changes. I know it's been a while, but do you have any other ideas?=) My sample project on github Post on stackoverflow

ttutisani commented 1 year ago

@alkoval, the idea is to understand what URL the live reloading tries to fetch and why it can't. You said you disabled the live reloading. That is why the problem is gone: it is not trying to connect to the backend to reload automatically. So you need first to enable the live reload and then check in the browser's network monitor to find the failing requests. You can use Chrome's dev tools and look at the Network tab or similar things in other browsers.

Once you find the failing request, decide what the public host must be. Remember that the client apps will be hosted under the paths like "/ClientApp1/" and "/ClientApp2/". The live reloading looks at the publicHost setting to decide where the request goes, so it has the wrong URL, which you need to fix.

I hope this helps.

alkoval commented 1 year ago

@ttutisani thank you for answer. The first client app is available at https://localhost:44313/. The second client app is available at https://localhost:44313/clientapp2 and in dev it reloads every time. I think this is because the DevServer has created a web socket at "url wss://localhost:44313/ng-cli-ws", when need to "url wss://localhost:44313/clientapp2/ng-cli-ws". In Chrome's dev tools(ClientApp2) i see that webpack-dev-server/client/index.js try to get socketURL:

var socketURL = createSocketURL(parsedResourceQuery);
socket(socketURL, onSocketMessage, options.reconnect);

And the hostname is wrong. If i change publicHost in angular.json for ClientApp2

"serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "publicHost": "clientapp2"
},

I get error WebSocket connection to 'wss://clientapp2:44313/ng-cli-ws' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED but the ClientApp2 is not reloading every time =)

Screenshot_641

I found a temporary solution when I added this to the file webpack-dev-server/client/index.js:

var socketURL = createSocketURL(parsedResourceQuery);
socketURL = socketURL.replace('ng-cli-ws', 'clientapp2/ng-cli-ws')
socket(socketURL, onSocketMessage, options.reconnect);

It doesn't look good=) But i don't understand what i need to change in ClientApp2 settings to get correct path for websocket.

ttutisani commented 1 year ago

@alkoval your configuration value for publicHost is missing slashes, can that be the reason?

You have:

"publicHost": "clientapp2"

You must have:

"publicHost": "/clientapp2/"
alkoval commented 1 year ago

@ttutisani I tried to set "publicHost": "/clientapp2/" but it didn't work. I have updated my sample project. Added ClientApp3 with two applications in the same workspace. Also live-reload doesn't work=)

I created issue (https://github.com/angular/angular-cli/issues/24572) where recommended to me use proxy and --serve-path. But if I add --serve-path=/clientapp 2 the project can't find the files. Base url(<base href="/clientapp2/"> or <base href="/">) doesn't change anything in this case. And the proxy config doesn't change the url for websocketclient. Phew...

exetroncorp commented 1 year ago

I am using a quick fix behing a reverse proxy because serve path doesn't fit my need, if someone has a better idea ....

go to

_node_modules/@angular-devkit/build-angular/src/webpack/configs/dev-server.js_

and modify the getPublicHostOptions like this for example my public host is https://francis.fr/app/gerard :


function getPublicHostOptions(options, webSocketPath) { let publicHost = options.publicHost; // if (publicHost) { // const hostWithProtocol = !/^\w+:\/\//.test(publicHost) ? https://${publicHost} : publicHost; // publicHost = new url_1.URL(hostWithProtocol).host; // } publicHost = "francis.fr/app/gerard"; return auto://${publicHost || '0.0.0.0:0'}${webSocketPath}; }