Always load NodeHttpClient to fix SSR (#8047)

This commit is contained in:
BrennanConroy 2019-03-04 09:16:52 -08:00 committed by GitHub
parent 7111c8ffd7
commit 508256d028
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 17 deletions

View File

@ -4,16 +4,9 @@
import { AbortError } from "./Errors";
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
import { ILogger } from "./ILogger";
import { NodeHttpClient } from "./NodeHttpClient";
import { XhrHttpClient } from "./XhrHttpClient";
let nodeHttpClientModule: any;
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
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
nodeHttpClientModule = requireFunc("./NodeHttpClient");
}
/** Default implementation of {@link @aspnet/signalr.HttpClient}. */
export class DefaultHttpClient extends HttpClient {
private readonly httpClient: HttpClient;
@ -24,10 +17,8 @@ export class DefaultHttpClient extends HttpClient {
if (typeof XMLHttpRequest !== "undefined") {
this.httpClient = new XhrHttpClient(logger);
} else if (typeof nodeHttpClientModule !== "undefined") {
this.httpClient = new nodeHttpClientModule.NodeHttpClient(logger);
} else {
throw new Error("No HttpClient could be created.");
this.httpClient = new NodeHttpClient(logger);
}
}

View File

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// This is an empty implementation of the NodeHttpClient that will be included in browser builds so the output file will be smaller
import { HttpClient, HttpResponse } from "./HttpClient";
import { ILogger } from "./ILogger";
export class NodeHttpClient extends HttpClient {
// @ts-ignore: Need ILogger to compile, but unused variables generate errors
public constructor(logger: ILogger) {
super();
}
public send(): Promise<HttpResponse> {
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."));
}
}

View File

@ -1,23 +1,36 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
import * as Request from "request";
// @ts-ignore: This will be removed from built files and is here to make the types available during dev work
import * as Request from "@types/request";
import { AbortError, HttpError, TimeoutError } from "./Errors";
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
import { ILogger, LogLevel } from "./ILogger";
import { isArrayBuffer } from "./Utils";
let requestModule: Request.RequestAPI<Request.Request, Request.CoreOptions, Request.RequiredUriUrl>;
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
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
requestModule = requireFunc("request");
}
export class NodeHttpClient extends HttpClient {
private readonly logger: ILogger;
private readonly request: Request.RequestAPI<Request.Request, Request.CoreOptions, Request.RequiredUriUrl>;
private readonly request: typeof requestModule;
private readonly cookieJar: Request.CookieJar;
public constructor(logger: ILogger) {
super();
if (typeof requestModule === "undefined") {
throw new Error("The 'request' module could not be loaded.");
}
this.logger = logger;
this.cookieJar = Request.jar();
this.request = Request.defaults({ jar: this.cookieJar });
this.cookieJar = requestModule.jar();
this.request = requestModule.defaults({ jar: this.cookieJar });
}
public send(httpRequest: HttpRequest): Promise<HttpResponse> {

View File

@ -40,7 +40,10 @@ module.exports = function (modulePath, browserBaseName, options) {
},
resolve: {
extensions: [".ts", ".js"],
alias: options.alias,
alias: {
"./NodeHttpClient": path.resolve(__dirname, "signalr/src/EmptyNodeHttpClient.ts"),
...options.alias,
}
},
output: {
filename: `${browserBaseName}.js`,
@ -73,7 +76,6 @@ module.exports = function (modulePath, browserBaseName, options) {
}),
// ES6 Promise uses this module in certain circumstances but we don't need it.
new webpack.IgnorePlugin(/vertx/),
new webpack.IgnorePlugin(/NodeHttpClient/),
new webpack.IgnorePlugin(/eventsource/),
],
externals: options.externals,