Search code examples
node.jsangularwebpacksignalrangular-cli

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


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

Solution

  • 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