Skip to content

Commit 93520b6

Browse files
Remove __non_webpack_require__ workaround and split Node dependencies correctly (#48154)
* Remove __non_webpack_require__ workaround and split Node dependencies correctly
1 parent 2240268 commit 93520b6

File tree

5 files changed

+98
-33
lines changed

5 files changed

+98
-33
lines changed

src/SignalR/clients/ts/signalr/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,14 @@
5959
},
6060
"resolutions": {
6161
"ansi-regex": "5.0.1"
62+
},
63+
"browser": {
64+
"./src/DynamicImports.ts": "./src/DynamicImports.browser.ts",
65+
"abort-controller": false,
66+
"eventsource": false,
67+
"fetch-cookie": false,
68+
"node-fetch": false,
69+
"ws": false,
70+
"tough-cookie": false
6271
}
6372
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
/** @private */
5+
export function configureFetch(): boolean {
6+
return false;
7+
}
8+
9+
/** @private */
10+
export function configureAbortController(): boolean {
11+
return false;
12+
}
13+
14+
/** @private */
15+
export function getWS(): any {
16+
throw new Error("Trying to import 'ws' in the browser.");
17+
}
18+
19+
/** @private */
20+
export function getEventSource(): any {
21+
throw new Error("Trying to import 'eventsource' in the browser.");
22+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
// @ts-ignore: This will be removed from built files and is here to make the types available during dev work
5+
import { CookieJar } from "@types/tough-cookie";
6+
import { Platform } from "./Utils";
7+
8+
/** @private */
9+
export function configureFetch(obj: { _fetchType?: (input: RequestInfo, init?: RequestInit) => Promise<Response>,
10+
_jar?: CookieJar }): boolean
11+
{
12+
// Node added a fetch implementation to the global scope starting in v18.
13+
// We need to add a cookie jar in node to be able to share cookies with WebSocket
14+
if (typeof fetch === "undefined" || Platform.isNode) {
15+
// Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests
16+
// eslint-disable-next-line @typescript-eslint/no-var-requires
17+
obj._jar = new (require("tough-cookie")).CookieJar();
18+
19+
if (typeof fetch === "undefined") {
20+
// eslint-disable-next-line @typescript-eslint/no-var-requires
21+
obj._fetchType = require("node-fetch");
22+
} else {
23+
// Use fetch from Node if available
24+
obj._fetchType = fetch;
25+
}
26+
27+
// node-fetch doesn't have a nice API for getting and setting cookies
28+
// fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one
29+
// eslint-disable-next-line @typescript-eslint/no-var-requires
30+
obj._fetchType = require("fetch-cookie")(obj._fetchType, obj._jar);
31+
return true;
32+
}
33+
return false;
34+
}
35+
36+
/** @private */
37+
export function configureAbortController(obj: { _abortControllerType: { prototype: AbortController, new(): AbortController } }): boolean {
38+
if (typeof AbortController === "undefined") {
39+
// Node needs EventListener methods on AbortController which our custom polyfill doesn't provide
40+
obj._abortControllerType = require("abort-controller");
41+
return true;
42+
}
43+
return false;
44+
}
45+
46+
/** @private */
47+
export function getWS(): any {
48+
return require("ws");
49+
}
50+
51+
/** @private */
52+
export function getEventSource(): any {
53+
return require("eventsource");
54+
}

src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { AbortError, HttpError, TimeoutError } from "./Errors";
88
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
99
import { ILogger, LogLevel } from "./ILogger";
1010
import { Platform, getGlobalThis, isArrayBuffer } from "./Utils";
11+
import { configureAbortController, configureFetch } from "./DynamicImports";
1112

1213
export class FetchHttpClient extends HttpClient {
1314
private readonly _abortControllerType: { prototype: AbortController, new(): AbortController };
@@ -20,38 +21,19 @@ export class FetchHttpClient extends HttpClient {
2021
super();
2122
this._logger = logger;
2223

23-
// Node added a fetch implementation to the global scope starting in v18.
24-
// We need to add a cookie jar in node to be able to share cookies with WebSocket
25-
if (typeof fetch === "undefined" || Platform.isNode) {
26-
// In order to ignore the dynamic require in webpack builds we need to do this magic
27-
// @ts-ignore: TS doesn't know about these names
28-
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
29-
30-
// Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests
31-
this._jar = new (requireFunc("tough-cookie")).CookieJar();
32-
33-
if (typeof fetch === "undefined") {
34-
this._fetchType = requireFunc("node-fetch");
35-
} else {
36-
// Use fetch from Node if available
37-
this._fetchType = fetch;
38-
}
39-
40-
// node-fetch doesn't have a nice API for getting and setting cookies
41-
// fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one
42-
this._fetchType = requireFunc("fetch-cookie")(this._fetchType, this._jar);
24+
// This is how you do "reference" arguments
25+
const fetchObj = { _fetchType: undefined, _jar: undefined };
26+
if (configureFetch(fetchObj)) {
27+
this._fetchType = fetchObj._fetchType!;
28+
this._jar = fetchObj._jar;
4329
} else {
4430
this._fetchType = fetch.bind(getGlobalThis());
4531
}
46-
if (typeof AbortController === "undefined") {
47-
// In order to ignore the dynamic require in webpack builds we need to do this magic
48-
// @ts-ignore: TS doesn't know about these names
49-
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
5032

51-
// Node needs EventListener methods on AbortController which our custom polyfill doesn't provide
52-
this._abortControllerType = requireFunc("abort-controller");
53-
} else {
54-
this._abortControllerType = AbortController;
33+
this._abortControllerType = AbortController;
34+
const abortObj = { _abortControllerType: this._abortControllerType };
35+
if (configureAbortController(abortObj)) {
36+
this._abortControllerType = abortObj._abortControllerType;
5537
}
5638
}
5739

src/SignalR/clients/ts/signalr/src/HttpConnection.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { AccessTokenHttpClient } from "./AccessTokenHttpClient";
55
import { DefaultHttpClient } from "./DefaultHttpClient";
6+
import { getEventSource, getWS } from "./DynamicImports";
67
import { AggregateErrors, DisabledTransportError, FailedToNegotiateWithServerError, FailedToStartTransportError, HttpError, UnsupportedTransportError, AbortError } from "./Errors";
78
import { IConnection } from "./IConnection";
89
import { IHttpConnectionOptions } from "./IHttpConnectionOptions";
@@ -86,11 +87,8 @@ export class HttpConnection implements IConnection {
8687
let eventSourceModule: any = null;
8788

8889
if (Platform.isNode && typeof require !== "undefined") {
89-
// In order to ignore the dynamic require in webpack builds we need to do this magic
90-
// @ts-ignore: TS doesn't know about these names
91-
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
92-
webSocketModule = requireFunc("ws");
93-
eventSourceModule = requireFunc("eventsource");
90+
webSocketModule = getWS();
91+
eventSourceModule = getEventSource();
9492
}
9593

9694
if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) {

0 commit comments

Comments
 (0)