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 { ILogger, LogLevel } from "./ILogger";
|
||||||
import { Platform } from "./Utils";
|
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 {
|
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;
|
private readonly logger: ILogger;
|
||||||
|
|
||||||
public constructor(logger: ILogger) {
|
public constructor(logger: ILogger) {
|
||||||
super();
|
super();
|
||||||
this.logger = logger;
|
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 */
|
/** @inheritDoc */
|
||||||
|
|
@ -54,7 +55,7 @@ export class FetchHttpClient extends HttpClient {
|
||||||
throw new Error("No url defined.");
|
throw new Error("No url defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const abortController = new abortControllerType();
|
const abortController = new this.abortControllerType();
|
||||||
|
|
||||||
let error: any;
|
let error: any;
|
||||||
// Hook our abortSignal into the abort controller
|
// Hook our abortSignal into the abort controller
|
||||||
|
|
@ -79,7 +80,7 @@ export class FetchHttpClient extends HttpClient {
|
||||||
|
|
||||||
let response: Response;
|
let response: Response;
|
||||||
try {
|
try {
|
||||||
response = await fetchType(request.url!, {
|
response = await this.fetchType(request.url!, {
|
||||||
body: request.content!,
|
body: request.content!,
|
||||||
cache: "no-cache",
|
cache: "no-cache",
|
||||||
credentials: request.withCredentials === true ? "include" : "same-origin",
|
credentials: request.withCredentials === true ? "include" : "same-origin",
|
||||||
|
|
@ -127,9 +128,9 @@ export class FetchHttpClient extends HttpClient {
|
||||||
|
|
||||||
public getCookieString(url: string): string {
|
public getCookieString(url: string): string {
|
||||||
let cookies: string = "";
|
let cookies: string = "";
|
||||||
if (Platform.isNode) {
|
if (Platform.isNode && this.jar) {
|
||||||
// @ts-ignore: unused variable
|
// @ts-ignore: unused variable
|
||||||
jar.getCookies(url, (e, c) => cookies = c.join("; "));
|
this.jar.getCookies(url, (e, c) => cookies = c.join("; "));
|
||||||
}
|
}
|
||||||
return cookies;
|
return cookies;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { WebSocketTransport } from "./WebSocketTransport";
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
const enum ConnectionState {
|
const enum ConnectionState {
|
||||||
Connecting = "Connecting ",
|
Connecting = "Connecting",
|
||||||
Connected = "Connected",
|
Connected = "Connected",
|
||||||
Disconnected = "Disconnected",
|
Disconnected = "Disconnected",
|
||||||
Disconnecting = "Disconnecting",
|
Disconnecting = "Disconnecting",
|
||||||
|
|
@ -39,16 +39,6 @@ export interface IAvailableTransport {
|
||||||
|
|
||||||
const MAX_REDIRECTS = 100;
|
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 */
|
/** @private */
|
||||||
export class HttpConnection implements IConnection {
|
export class HttpConnection implements IConnection {
|
||||||
private connectionState: ConnectionState;
|
private connectionState: ConnectionState;
|
||||||
|
|
@ -88,19 +78,30 @@ export class HttpConnection implements IConnection {
|
||||||
throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");
|
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) {
|
if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) {
|
||||||
options.WebSocket = WebSocket;
|
options.WebSocket = WebSocket;
|
||||||
} else if (Platform.isNode && !options.WebSocket) {
|
} else if (Platform.isNode && !options.WebSocket) {
|
||||||
if (WebSocketModule) {
|
if (webSocketModule) {
|
||||||
options.WebSocket = WebSocketModule;
|
options.WebSocket = webSocketModule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Platform.isNode && typeof EventSource !== "undefined" && !options.EventSource) {
|
if (!Platform.isNode && typeof EventSource !== "undefined" && !options.EventSource) {
|
||||||
options.EventSource = EventSource;
|
options.EventSource = EventSource;
|
||||||
} else if (Platform.isNode && !options.EventSource) {
|
} else if (Platform.isNode && !options.EventSource) {
|
||||||
if (typeof EventSourceModule !== "undefined") {
|
if (typeof eventSourceModule !== "undefined") {
|
||||||
options.EventSource = EventSourceModule;
|
options.EventSource = eventSourceModule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue