Skip to content

Commit aef62d9

Browse files
BrennanConroyEilon
authored andcommitted
Backport SSR fix (#8174)
1 parent 4cbc33d commit aef62d9

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,9 @@
44
import { AbortError } from "./Errors";
55
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
66
import { ILogger } from "./ILogger";
7+
import { NodeHttpClient } from "./NodeHttpClient";
78
import { XhrHttpClient } from "./XhrHttpClient";
89

9-
let nodeHttpClientModule: any;
10-
if (typeof XMLHttpRequest === "undefined") {
11-
// In order to ignore the dynamic require in webpack builds we need to do this magic
12-
// @ts-ignore: TS doesn't know about these names
13-
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
14-
nodeHttpClientModule = requireFunc("./NodeHttpClient");
15-
}
16-
1710
/** Default implementation of {@link @aspnet/signalr.HttpClient}. */
1811
export class DefaultHttpClient extends HttpClient {
1912
private readonly httpClient: HttpClient;
@@ -24,10 +17,8 @@ export class DefaultHttpClient extends HttpClient {
2417

2518
if (typeof XMLHttpRequest !== "undefined") {
2619
this.httpClient = new XhrHttpClient(logger);
27-
} else if (typeof nodeHttpClientModule !== "undefined") {
28-
this.httpClient = new nodeHttpClientModule.NodeHttpClient(logger);
2920
} else {
30-
throw new Error("No HttpClient could be created.");
21+
this.httpClient = new NodeHttpClient(logger);
3122
}
3223
}
3324

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
// This is an empty implementation of the NodeHttpClient that will be included in browser builds so the output file will be smaller
5+
6+
import { HttpClient, HttpResponse } from "./HttpClient";
7+
import { ILogger } from "./ILogger";
8+
9+
export class NodeHttpClient extends HttpClient {
10+
// @ts-ignore: Need ILogger to compile, but unused variables generate errors
11+
public constructor(logger: ILogger) {
12+
super();
13+
}
14+
15+
public send(): Promise<HttpResponse> {
16+
return Promise.reject(new Error("If using Node either provide an XmlHttpRequest polyfill or consume the cjs or esm script instead of the browser/signalr.js one."));
17+
}
18+
}

src/SignalR/clients/ts/signalr/src/NodeHttpClient.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4-
import * as Request from "request";
4+
// @ts-ignore: This will be removed from built files and is here to make the types available during dev work
5+
import * as Request from "@types/request";
56

67
import { AbortError, HttpError, TimeoutError } from "./Errors";
78
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
89
import { ILogger, LogLevel } from "./ILogger";
910
import { isArrayBuffer } from "./Utils";
1011

12+
let requestModule: Request.RequestAPI<Request.Request, Request.CoreOptions, Request.RequiredUriUrl>;
13+
if (typeof XMLHttpRequest === "undefined") {
14+
// In order to ignore the dynamic require in webpack builds we need to do this magic
15+
// @ts-ignore: TS doesn't know about these names
16+
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
17+
requestModule = requireFunc("request");
18+
}
19+
1120
export class NodeHttpClient extends HttpClient {
1221
private readonly logger: ILogger;
13-
private readonly request: Request.RequestAPI<Request.Request, Request.CoreOptions, Request.RequiredUriUrl>;
22+
private readonly request: typeof requestModule;
1423
private readonly cookieJar: Request.CookieJar;
1524

1625
public constructor(logger: ILogger) {
1726
super();
27+
if (typeof requestModule === "undefined") {
28+
throw new Error("The 'request' module could not be loaded.");
29+
}
30+
1831
this.logger = logger;
19-
this.cookieJar = Request.jar();
20-
this.request = Request.defaults({ jar: this.cookieJar });
32+
this.cookieJar = requestModule.jar();
33+
this.request = requestModule.defaults({ jar: this.cookieJar });
2134
}
2235

2336
public send(httpRequest: HttpRequest): Promise<HttpResponse> {

src/SignalR/clients/ts/webpack.config.base.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ module.exports = function (modulePath, browserBaseName, options) {
3939
},
4040
resolve: {
4141
extensions: [".ts", ".js"],
42-
alias: options.alias,
42+
alias: {
43+
"./NodeHttpClient": path.resolve(__dirname, "signalr/src/EmptyNodeHttpClient.ts"),
44+
...options.alias,
45+
}
4346
},
4447
output: {
4548
filename: `${browserBaseName}.js`,
@@ -72,7 +75,6 @@ module.exports = function (modulePath, browserBaseName, options) {
7275
}),
7376
// ES6 Promise uses this module in certain circumstances but we don't need it.
7477
new webpack.IgnorePlugin(/vertx/),
75-
new webpack.IgnorePlugin(/NodeHttpClient/),
7678
new webpack.IgnorePlugin(/eventsource/),
7779
],
7880
externals: options.externals,

0 commit comments

Comments
 (0)