dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.36k stars 9.99k forks source link

Angular SSR on Azure App Services - Cannot find module 'request' #21059

Closed DumbTechLion closed 4 years ago

DumbTechLion commented 4 years ago

Hello there,

We just upgraded our API from .NET Framework to .NET Core. We migrated to SignalR Core. So, we had to upgrade our SignalR client as well. No problem. Everything works on local. But when we deploy on our Azure App Service, we get this error :

Error: Cannot find module 'request'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (D:\home\site\wwwroot\server.js:276222:21)
    at webpack_require (D:\home\site\wwwroot\server.js:20:30)
    at Object.@microsoft/signalr (D:\home\site\wwwroot\server.js:264546:18)
    at webpack_require (D:\home\site\wwwroot\server.js:248813:30)
    at Object../src/app/shared/services/signalR/signarRService.ts (D:\home\site\wwwroot\server.js:263030:17)
    at webpack_require (D:\home\site\wwwroot\server.js:248813:30)

I checked and we can find signalr.js files in dist/browser. We're on the last package version. Everything related found on internet didn't help even a bit.

With SignalR Framework version, everything worked just fine.

It has been one week we're working on it. But still, we don't understand why it keeps happening. What we tried :

Our angular service

import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { Store } from '@ngrx/store';
import { AppState } from '../../../store/core.state';
import { DoUpdateStatusAccountAuditedAction } from '../../../store/customer/customer.actions';
import { GoogleAdsAccountDTO } from '../../dto/googleAdsAcoountDto';
import { SubscribeAccountStatusUpdateRequestDto } from '../../dto/SubscribeAccountStatusUpdateRequestDto';
import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr';

@Injectable({
    providedIn: 'root'
})
export class SignalRService {

    private readonly frontHub: string = 'FrontHub';
    private readonly BroadCastAuditStatus: string = 'BroadCastAuditStatus';
    private readonly SubscribeToAuditStatutUpdate: string = 'SubscribeToAuditStatutUpdate';

    private hubConnection: HubConnection;

    constructor(private store: Store<AppState>) {}

    public listenToAuditedAccountStatus(accountIds: Array<string>, userId: number) {
        const subscribeAccountStatusUpdateRequest = new SubscribeAccountStatusUpdateRequestDto(userId, accountIds);
        if (this.hubConnection &&
            this.hubConnection.state === HubConnectionState.Connected) {
            this.subscribeToAuditStatutUpdate(subscribeAccountStatusUpdateRequest);
        } else {
            this.startConnection().then(() => {
                this.subscribeToAuditStatutUpdate(subscribeAccountStatusUpdateRequest);
            });
        }
    }

    private startConnection() {
        this.hubConnection = new HubConnectionBuilder()
          .withUrl(environment.webSignalR + '/' + this.frontHub)
          .build();

        this.hubConnection.on(this.BroadCastAuditStatus, (googleAdsAccountDto: GoogleAdsAccountDTO) => {
            this.store.dispatch(DoUpdateStatusAccountAuditedAction({ payload: googleAdsAccountDto }));
        });

        return this.hubConnection.start()
        .then(() => console.log('Connection started!'))
        .catch(err => console.log('Error while establishing connection :('));
    }

    private subscribeToAuditStatutUpdate = (subscribeAccountStatusUpdateRequest: SubscribeAccountStatusUpdateRequestDto) => {
        this.hubConnection.invoke(this.SubscribeToAuditStatutUpdate, subscribeAccountStatusUpdateRequest);
    }
}

Package.json

{
  "name": "seiso",
  "version": "1.0.0",
  "private": true,
  "description": "",
  "scripts": {
    "ng": "ng",
    "build": "ng build --prod",
    "start": "ng serve",
    "test": "ng test",
    "lint": "tslint ./src/**/*.ts -t verbose",
    "e2e": "ng e2e",
    "start:fr": "ng serve --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr",
    "build:fr": "ng build --prod --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr",
    "extract": "ng xi18n --outputPath=src/locale",
    "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
    "build:ssr:staging": "npm run build:client-and-server-bundles-staging && npm run webpack:server",
    "build:ssr:testing": "npm run build:client-and-server-bundles-testing && npm run webpack:server",
    "serve:ssr": "node dist/server",
    "build:client-and-server-bundles": "ng build --prod && ng run seiso:server:production",
    "build:client-and-server-bundles-staging": "ng build --configuration=staging && ng run seiso:server:staging",
    "build:client-and-server-bundles-testing": "ng build --configuration=testing && ng run seiso:server:testing",
    "webpack:server": "webpack --config webpack.server.config.js --progress --colors",
    "prepare-azure-app": "copy web.config dist && cd dist && mkdir dist && mv browser server ./dist"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@angular/animations": "^8.1.1",
    "@angular/cdk": "^8.0.2",
    "@angular/common": "^8.1.1",
    "@angular/compiler": "^8.1.1",
    "@angular/core": "^8.1.1",
    "@angular/forms": "^8.1.1",
    "@angular/material": "^8.0.2",
    "@angular/platform-browser": "^8.1.1",
    "@angular/platform-browser-dynamic": "^8.1.1",
    "@angular/platform-server": "^8.1.1",
    "@angular/router": "^8.1.1",
    "@gilsdav/ngx-translate-router": "~2.0.1",
    "@gilsdav/ngx-translate-router-http-loader": "~1.0.0",
    "@microsoft/signalr": "^3.1.2",
    "@ngrx/effects": "^8.2.0",
    "@ngrx/store": "^8.2.0",
    "@ngrx/store-devtools": "^6.0.0",
    "@nguniversal/express-engine": "~8.1.1",
    "@nguniversal/module-map-ngfactory-loader": "~8.1.1",
    "@ngx-cache/core": "~7.0.0",
    "@ngx-translate/core": "~11.0.1",
    "@ngx-translate/http-loader": "~4.0.0",
    "@nicky-lenaers/ngx-scroll-to": "^2.0.0",
    "angular-in-memory-web-api": "~0.8.0",
    "core-js": "~2.5.7",
    "express": "^4.15.2",
    "hammerjs": "^2.0.8",
    "localize-router-lazy-universal-module-loader": "1.0.0-ntr",
    "moment": "^2.24.0",
    "ngx-clipboard": "^12.2.0",
    "ngx-countdown": "^8.0.3",
    "ngx-custom-validators": "^8.0.0",
    "ngx-device-detector": "^1.3.9",
    "roboto-fontface": "^0.10.0",
    "rxjs": "~6.4.0",
    "ts-loader": "~5.3.0",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.800.0",
    "@angular/cli": "~8.0.1",
    "@angular/compiler-cli": "^8.1.1",
    "@angular/language-service": "^8.1.1",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "codelyzer": "^5.0.0",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "karma-phantomjs-launcher": "~1.0.2",
    "lodash": "^4.17.14",
    "phantomjs-prebuilt": "^2.1.7",
    "protractor": "~5.4.0",
    "ts-loader": "^5.2.0",
    "ts-node": "~7.0.1",
    "tslint": "~5.15.0",
    "typescript": "~3.4.3",
    "webpack-cli": "^3.3.6"
  },
  "repository": {}
}
BrennanConroy commented 4 years ago

Dupe of https://github.com/dotnet/aspnetcore/issues/10400

This is fixed in 5.0.

I believe some folks have had success with workarounds like: https://github.com/dotnet/aspnetcore/issues/10400#issuecomment-506362739

DumbTechLion commented 4 years ago

Not really a duplicate since it's not the same package version and it's not the same environment. It seems it doesn't work EVERYWHERE for this person. For us, it works on local but not on Azure.

But nevermind. I just fixed that. I found that not one but three dependencies where missing. So I added a task in my pipeline Azure DevOps, just after "npm install" : npm install request eventsource ws.

If your node version is too old on your app service, "ws" won't compile. So in my Azure App Service Configurations, I set "WEBSITE_NODE_DEFAULT_VERSION" from 6.3.1 to 10.16.3.

Reboot your app service and relaunch your pipeline.

I hope it will help people with this issue !

analogrelay commented 4 years ago

Closing, as it sounds like this issue was related to Azure App Service configuration. Let us know if I'm misinterpreting your response though!

DumbTechLion commented 4 years ago

No, that's absolutely not what I said. It's not normal that I need to manually install these modules on my built SSR angular. If node_modules with request, eventsource and ws are not present in server.js folder, there is that error. You shouldn't have to do this. So, that's not a misconfiguration.

BrennanConroy commented 4 years ago

Could you try using the latest preview and seeing if that resolves the issue? https://www.npmjs.com/package/@microsoft/signalr/v/5.0.0-preview.3.20215.14

parys commented 4 years ago

@BrennanConroy looks like yes, 5.0.0-preview.3.20215.14 works without manual manipulations. When I used 3.1.3 It failed in the same way, as author's.

ghost commented 4 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.

hez2010 commented 4 years ago

Already fixed via https://github.com/dotnet/aspnetcore/pull/19832, please try out version 5.0.0-preview.3.20215.14 of @microsoft/signalr.

DumbTechLion commented 4 years ago

You can't ask a company to test a preview version in production. That's the definition of "preview". You don't. And we certainly won't upgrade to 5.0 until a good reason shows up. I don't understand why you won't fix it on Core 3.1. It's freaking LTS !

BrennanConroy commented 4 years ago

You can't ask a company to test a preview version in production

We aren't asking you to use it in production. It would be nice if you could try it out in a test environment and verify that the issue is fixed in 5.0.

I don't understand why you won't fix it on Core 3.1

We don't backport every change we make as there are risks associated with that. We have a doc talking about the requirements needed to be fulfilled in order to backport a change: https://github.com/dotnet/aspnetcore/blob/master/docs/Servicing.md#servicing-bar Because this issue has a workaround and multiple people have successfully applied the workaround it generally will not meet the requirements for servicing.

BrennanConroy commented 4 years ago

Closing as there is a workaround (and it's fixed in 5.0) and we likely wont backport.