Angular 18 and SignalR error when building app : [ERROR] Could not resolve "url", "https", "http", "util" from eventsource
Asked Answered
K

2

5

In an Angular 18 application, I need to add real-time technology. The chosen technology is SignalR, but I'm having trouble adding the package and getting a successful build. It seems the error is related to the build process, possibly because Angular is no longer using webpack. I don't know how to fix it. Any thoughts?

We can recreate the error by creating a sample Angular project and adding the @microsoft/signalr package:

Create a new Angular project

ng new angular-signalr

Add SignalR dependency:

pnpm install @microsoft/signalr --save

Create a Angular Service to connect to SignalR

ng g service services/SignalR

Add Signal R import and init code:

import { Injectable } from '@angular/core';

import * as signalR from '@microsoft/signalr';

//Same error when importing this way
//import { HubConnectionBuilder, HubConnection } from '@microsoft/signalr';

@Injectable({
    providedIn: 'root'
})
export class SignalRService
{
    #HubConnection: signalR.HubConnection;

    constructor()
    {
        this.#HubConnection = new signalR.HubConnectionBuilder()
        .withUrl('https://sample.signalr.mydomain.com')
        .build();

        //Same error when instantiating this way
        // this.#HubConnection = new HubConnectionBuilder()
        //  .withUrl('https://sample.signalr.mydomain.com')
        //  .build();
    }

    Init()
    {
        this.#HubConnection
            .start()
            .then(() => console.log('Connection started'))
            .catch(error => console.error('Error while starting connection: ' + error));
    }
}

Inject the SignalR service to be included in build and run a prod build

import { Component, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { SignalRService } from './services/signal-r.service';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {

  #SignalRService = inject(SignalRService);

  title = 'angular-signalr';
}

Run a production build:

ng build --configuration=production

And the following error will occour:

Application bundle generation failed. [3.228 seconds]

X [ERROR] Could not resolve "url"

    (disabled):node_modules/eventsource/lib/eventsource.js:1:20:
      1 │ var parse = require('url').parse;
        ╵                     ~~~~~

  The package "url" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.


X [ERROR] Could not resolve "https"

    (disabled):node_modules/eventsource/lib/eventsource.js:3:20:
      3 │ var https = require('https');
        ╵                     ~~~~~~~

  The package "https" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.


X [ERROR] Could not resolve "http"

    (disabled):node_modules/eventsource/lib/eventsource.js:4:19:
      4 │ var http = require('http');
        ╵                    ~~~~~~

  The package "http" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.


X [ERROR] Could not resolve "util"

    (disabled):node_modules/eventsource/lib/eventsource.js:5:19:
      5 │ var util = require('util');
        ╵                    ~~~~~~

  The package "util" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

This are my Angular project version (ng --info)

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 18.0.3
Node: 20.14.0
Package Manager: npm 10.7.0
OS: win32 x64

Angular: 18.0.3
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1800.3
@angular-devkit/build-angular   18.0.3
@angular-devkit/core            18.0.3
@angular-devkit/schematics      18.0.3
@schematics/angular             18.0.3
rxjs                            7.8.1
typescript                      5.4.5
zone.js                         0.14.7
Kasten answered 13/6 at 13:45 Comment(0)
L
8

This issue is already documented in github issue signalr, we have to add "http", "https", "url", "util", "net" to make the build pass, then we can add "allowedCommonJsDependencies" array which is optional to get rid of some build warnings.

    ...
    "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            "externalDependencies": ["http", "https", "url", "util", "net"],
            "allowedCommonJsDependencies": [
              "tough-cookie",
              "node-fetch",
              "fetch-cookie",
              "abort-controller",
              "ws",
              "eventsource"
            ],
            ...

Stackblitz Demo

Lombardi answered 13/6 at 14:9 Comment(1)
I searched the repo, but somehow I could not find that issue. I tested your solution and other workarounds suggested on the GitHub issue. It's working! Thank you so much for the help.Kasten
H
1

This issue got fixed in @microsoft/signalr version 8.0.7.

Sorry this took so long, 8.0.7 (out now) should contain a fix for this so any workarounds listed above can now be removed.

Source: Github Issue

Headlong answered 10/7 at 6:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.