Aspnetcore: SignalR NodeHttpClient module not found - Angular SSR

Created on 21 Feb 2019  路  12Comments  路  Source: dotnet/aspnetcore

Describe the bug

This is the same exact as: https://github.com/aspnet/SignalR/issues/3254

When using SignalR with Angular in SSR it throws an error (using Angular7, template with CLI - based on .NET Angular official Template to be exact)

NodeInvocationException: Prerendering failed because of error: Error: Cannot find module './NodeHttpClient'

Additional context

  • @aspnet/signalr: v1.1.2 (latest)

After diagnosing some, basically NodeHttpClient, which is imported only on Node, is being imported relatively e.g.

// bundled code
var nodeHttpClientModule;
if (typeof XMLHttpRequest === "undefined") {
    // In order to ignore the dynamic require in webpack builds we need to do this magic
    // @ts-ignore: TS doesn't know about these names
    var requireFunc =  true ? require : undefined;
    nodeHttpClientModule = requireFunc("./NodeHttpClient");
}

SSR App is bundled (dist/main.js), hence this file does not exists relative to ./dist/main.js file at runtime

So i guess it should be either:

  • Somehow webpack bundles it if its node only
  • Imported also for browser, but will eventually gets treeshaked
area-signalr

Most helpful comment

This has been merged.

All 12 comments

@muratg This looks like it's worth patching.

@BrennanConroy could you take the initial look to see what a patch may look like?

If you would need a repro project which you can use to test, I should be able to provide (but would need some time to simplify it a bit)

Yes please, I tried out the dotnet new angular template and it seems to work fine.

Yes, thats because it does not bundle server (even prod build) and SSR its not enabled by default either (unless you configured it).

I will try to provide you the sample, probably in the coming 2days

I managed to get it up quickly

repo: https://github.com/sketch7/dotnet-ngx-sample/tree/signalr-ssr-error

To get started

git clone https://github.com/sketch7/dotnet-ngx-sample.git -b signalr-ssr-error
npm start
explorer https://localhost:5001/fetch-data

NOTE: I installed signalr via @ssv/signalr-client not signalr-client directly (which is our library), but all its doing at that point is creating a new Hub instance. Feel free to change it directly to @aspnet/signalr

Hope it helps, thanks!

Thanks for the repro it helped a lot!

After discussing with Andrew and Steve we're going to look at not trying to be clever and just including the import always. From a quick test it looks like this only adds a couple kb to the .js file.

Glad it was useful!

Yes sometimes simple is better, and there's a possibility that it gets treeshaked with the build (not sure how its used exactly tho, so might not be the case).

Thanks for pointing me to https://github.com/sketch7/signalr-client @stephenlautier. It's nice to see how other people have approached adding automatic reconnects to the JS client.

we're going to look at not trying to be clever and just including the import always. From a quick test it looks like this only adds a couple kb to the .js file.

I don't like adding a couple KB to the browser and webworker dists for no reason. I don't think either of these dists ever run on node.js. If you look at the the full NodeInvocationException, you can tell that the bundler used the cjs dist. I think always including the import in the cjs and esm dists is probably fine.

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: Prerendering failed because of error: Error: Cannot find module './NodeHttpClient'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:613:15)
    at Function.Module._load (internal/modules/cjs/loader.js:539:25)
    at Module.require (internal/modules/cjs/loader.js:667:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object../node_modules/@aspnet/signalr/dist/cjs/DefaultHttpClient.js (C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx\ClientApp\dist-server\main.js:86548:28)
    at __webpack_require__ (C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx\ClientApp\dist-server\main.js:20:30)
    at Object../node_modules/@aspnet/signalr/dist/cjs/index.js (C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx\ClientApp\dist-server\main.js:89165:27)
    at __webpack_require__ (C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx\ClientApp\dist-server\main.js:20:30)
    at Module../node_modules/@ssv/signalr-client/dist/es2015/hub-connection.factory.js (C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx\ClientApp\dist-server\main.js:91187:73)
    at __webpack_require__ (C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx\ClientApp\dist-server\main.js:20:30)
Current directory is: C:\dev\halter73\dotnet-ngx-sample\Sketch7.DotnetNgx

   at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.InvokeExportAsync[T](NodeInvocationInfo invocationInfo, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.InvokeExportAsync[T](CancellationToken cancellationToken, String moduleName, String exportNameOrNull, Object[] args)
   at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.InvokeExportWithPossibleRetryAsync[T](String moduleName, String exportedFunctionName, Object[] args, Boolean allowRetry, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.InvokeExportWithPossibleRetryAsync[T](String moduleName, String exportedFunctionName, Object[] args, Boolean allowRetry, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Builder.SpaPrerenderingExtensions.<>c__DisplayClass0_0.<<UseSpaPrerendering>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]

This has been merged.

Is this fixed? After updating to package 1.1.4, the Cannot find module './NodeHttpClient' is gone but now I have this error:

NodeInvocationException: Prerendering failed because of error: Error: Cannot find module 'request' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15) at Function.Module._load (internal/modules/cjs/loader.js:506:25) at Module.require (internal/modules/cjs/loader.js:636:17) at require (internal/modules/cjs/helpers.js:20:18) at Object../node_modules/@aspnet/signalr/dist/cjs/NodeHttpClient.js

File a new issue with the details of the problem you're seeing. We don't track closed issues.

Was this page helpful?
0 / 5 - 0 ratings