Fix SSR issues for SignalR: require is not defined (#19832)
This commit is contained in:
parent
44230d36a7
commit
56d50e677b
|
|
@ -9,35 +9,36 @@ import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
|
|||
import { ILogger, LogLevel } from "./ILogger";
|
||||
import { Platform } from "./Utils";
|
||||
|
||||
let abortControllerType: { prototype: AbortController, new(): AbortController };
|
||||
let fetchType: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
||||
let jar: tough.CookieJar;
|
||||
if (typeof fetch === "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;
|
||||
|
||||
// Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests
|
||||
jar = new (requireFunc("tough-cookie")).CookieJar();
|
||||
fetchType = requireFunc("node-fetch");
|
||||
|
||||
// node-fetch doesn't have a nice API for getting and setting cookies
|
||||
// fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one
|
||||
fetchType = requireFunc("fetch-cookie")(fetchType, jar);
|
||||
|
||||
// Node needs EventListener methods on AbortController which our custom polyfill doesn't provide
|
||||
abortControllerType = requireFunc("abort-controller");
|
||||
} else {
|
||||
fetchType = fetch;
|
||||
abortControllerType = AbortController;
|
||||
}
|
||||
|
||||
export class FetchHttpClient extends HttpClient {
|
||||
private readonly abortControllerType: { prototype: AbortController, new(): AbortController };
|
||||
private readonly fetchType: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
||||
private readonly jar?: tough.CookieJar;
|
||||
|
||||
private readonly logger: ILogger;
|
||||
|
||||
public constructor(logger: ILogger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
|
||||
if (typeof fetch === "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;
|
||||
|
||||
// Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests
|
||||
this.jar = new (requireFunc("tough-cookie")).CookieJar();
|
||||
this.fetchType = requireFunc("node-fetch");
|
||||
|
||||
// node-fetch doesn't have a nice API for getting and setting cookies
|
||||
// fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one
|
||||
this.fetchType = requireFunc("fetch-cookie")(this.fetchType, this.jar);
|
||||
|
||||
// Node needs EventListener methods on AbortController which our custom polyfill doesn't provide
|
||||
this.abortControllerType = requireFunc("abort-controller");
|
||||
} else {
|
||||
this.fetchType = fetch.bind(self);
|
||||
this.abortControllerType = AbortController;
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
|
@ -54,7 +55,7 @@ export class FetchHttpClient extends HttpClient {
|
|||
throw new Error("No url defined.");
|
||||
}
|
||||
|
||||
const abortController = new abortControllerType();
|
||||
const abortController = new this.abortControllerType();
|
||||
|
||||
let error: any;
|
||||
// Hook our abortSignal into the abort controller
|
||||
|
|
@ -79,7 +80,7 @@ export class FetchHttpClient extends HttpClient {
|
|||
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetchType(request.url!, {
|
||||
response = await this.fetchType(request.url!, {
|
||||
body: request.content!,
|
||||
cache: "no-cache",
|
||||
credentials: request.withCredentials === true ? "include" : "same-origin",
|
||||
|
|
@ -127,9 +128,9 @@ export class FetchHttpClient extends HttpClient {
|
|||
|
||||
public getCookieString(url: string): string {
|
||||
let cookies: string = "";
|
||||
if (Platform.isNode) {
|
||||
if (Platform.isNode && this.jar) {
|
||||
// @ts-ignore: unused variable
|
||||
jar.getCookies(url, (e, c) => cookies = c.join("; "));
|
||||
this.jar.getCookies(url, (e, c) => cookies = c.join("; "));
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { WebSocketTransport } from "./WebSocketTransport";
|
|||
|
||||
/** @private */
|
||||
const enum ConnectionState {
|
||||
Connecting = "Connecting ",
|
||||
Connecting = "Connecting",
|
||||
Connected = "Connected",
|
||||
Disconnected = "Disconnected",
|
||||
Disconnecting = "Disconnecting",
|
||||
|
|
@ -39,16 +39,6 @@ export interface IAvailableTransport {
|
|||
|
||||
const MAX_REDIRECTS = 100;
|
||||
|
||||
let WebSocketModule: any = null;
|
||||
let EventSourceModule: any = null;
|
||||
if (Platform.isNode && typeof require !== "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;
|
||||
WebSocketModule = requireFunc("ws");
|
||||
EventSourceModule = requireFunc("eventsource");
|
||||
}
|
||||
|
||||
/** @private */
|
||||
export class HttpConnection implements IConnection {
|
||||
private connectionState: ConnectionState;
|
||||
|
|
@ -88,19 +78,30 @@ export class HttpConnection implements IConnection {
|
|||
throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");
|
||||
}
|
||||
|
||||
let webSocketModule: any = null;
|
||||
let eventSourceModule: any = null;
|
||||
|
||||
if (Platform.isNode && typeof require !== "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;
|
||||
webSocketModule = requireFunc("ws");
|
||||
eventSourceModule = requireFunc("eventsource");
|
||||
}
|
||||
|
||||
if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) {
|
||||
options.WebSocket = WebSocket;
|
||||
} else if (Platform.isNode && !options.WebSocket) {
|
||||
if (WebSocketModule) {
|
||||
options.WebSocket = WebSocketModule;
|
||||
if (webSocketModule) {
|
||||
options.WebSocket = webSocketModule;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Platform.isNode && typeof EventSource !== "undefined" && !options.EventSource) {
|
||||
options.EventSource = EventSource;
|
||||
} else if (Platform.isNode && !options.EventSource) {
|
||||
if (typeof EventSourceModule !== "undefined") {
|
||||
options.EventSource = EventSourceModule;
|
||||
if (typeof eventSourceModule !== "undefined") {
|
||||
options.EventSource = eventSourceModule;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue