@module-federation/devtools 2.3.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,6 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
- var __hasOwnProp = Object.prototype.hasOwnProperty;
4
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __spreadValues = (a, b) => {
7
- for (var prop in b || (b = {}))
8
- if (__hasOwnProp.call(b, prop))
9
- __defNormalProp(a, prop, b[prop]);
10
- if (__getOwnPropSymbols)
11
- for (var prop of __getOwnPropSymbols(b)) {
12
- if (__propIsEnum.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- }
15
- return a;
16
- };
17
- var __objRest = (source, exclude) => {
18
- var target = {};
19
- for (var prop in source)
20
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
21
- target[prop] = source[prop];
22
- if (source != null && __getOwnPropSymbols)
23
- for (var prop of __getOwnPropSymbols(source)) {
24
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
25
- target[prop] = source[prop];
26
- }
27
- return target;
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __commonJS = (cb, mod) => function __require() {
3
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
28
4
  };
29
5
  var __async = (__this, __arguments, generator) => {
30
6
  return new Promise((resolve, reject) => {
@@ -46,173 +22,321 @@ var __async = (__this, __arguments, generator) => {
46
22
  step((generator = generator.apply(__this, __arguments)).next());
47
23
  });
48
24
  };
49
- var _a;
50
- import { loadScript } from "@module-federation/sdk";
51
- import { isObject, getUnpkgUrl } from "../index";
25
+ import { getUnpkgUrl } from "../index";
52
26
  import { definePropertyGlobalVal } from "../sdk";
53
27
  import {
54
28
  __FEDERATION_DEVTOOLS__,
55
29
  __EAGER_SHARE__,
56
30
  __ENABLE_FAST_REFRESH__
57
31
  } from "../../template/constant";
58
- const SUPPORT_PKGS = ["react", "react-dom"];
59
- const fetchAndExecuteUmdSync = (url) => {
60
- try {
61
- const response = new XMLHttpRequest();
62
- response.open("GET", url, false);
63
- response.overrideMimeType("text/plain");
64
- response.send();
65
- if (response.status === 200) {
66
- const scriptContent = response.responseText;
67
- const moduleFunction = new Function(scriptContent);
68
- return moduleFunction(window);
69
- } else {
70
- throw new Error(
71
- `Failed to load module from ${url}: HTTP ${response.status}`
32
+ var require_fast_refresh = __commonJS({
33
+ "src/utils/chrome/fast-refresh.ts"(exports) {
34
+ var _a;
35
+ const SUPPORT_PKGS = ["react", "react-dom"];
36
+ const DEFAULT_SHARE_SCOPE = "default";
37
+ const DEFAULT_GLOBAL_KEY_MAP = {
38
+ react: "React",
39
+ "react-dom": "ReactDOM"
40
+ };
41
+ const sanitizeWindowKey = (value) => value.replace(/[^a-zA-Z0-9_$]/g, "_");
42
+ const getShareScopes = (scope) => Array.isArray(scope) && scope.length ? scope : [DEFAULT_SHARE_SCOPE];
43
+ const getDefaultGlobalKey = (pkgName) => DEFAULT_GLOBAL_KEY_MAP[pkgName];
44
+ const getScopedGlobalKey = (scope, pkgName) => `${sanitizeWindowKey(scope)}_${sanitizeWindowKey(pkgName)}`;
45
+ const getWindowValue = (key) => window[key];
46
+ const setWindowValue = (key, value) => {
47
+ window[key] = value;
48
+ };
49
+ const setScopeGlobals = (pkgName, scopes, source) => {
50
+ if (!source) {
51
+ return source;
52
+ }
53
+ scopes.forEach((scope) => {
54
+ setWindowValue(getScopedGlobalKey(scope, pkgName), source);
55
+ });
56
+ return source;
57
+ };
58
+ const getScopeGlobal = (pkgName, scopes) => {
59
+ for (const scope of scopes) {
60
+ const scopeGlobal = getWindowValue(getScopedGlobalKey(scope, pkgName));
61
+ if (scopeGlobal) {
62
+ return scopeGlobal;
63
+ }
64
+ }
65
+ return void 0;
66
+ };
67
+ const getEagerShareInfo = (eagerShare) => {
68
+ if (!Array.isArray(eagerShare) || eagerShare.length < 2) {
69
+ return null;
70
+ }
71
+ const [, version, scopes] = eagerShare;
72
+ if (typeof version !== "string") {
73
+ return null;
74
+ }
75
+ return {
76
+ version,
77
+ scopes: getShareScopes(scopes)
78
+ };
79
+ };
80
+ const updateEagerShareInfo = (devtoolsMessage2, pkgName, version, scopes) => {
81
+ const existing = getEagerShareInfo(devtoolsMessage2[__EAGER_SHARE__]);
82
+ const mergedScopes = Array.from(
83
+ /* @__PURE__ */ new Set([...(existing == null ? void 0 : existing.scopes) || [], ...scopes])
72
84
  );
73
- }
74
- } catch (error) {
75
- throw new Error(`Failed to fetch module from ${url}: ${error.message}`);
76
- }
77
- };
78
- const getDevtoolsMessage = () => {
79
- const devtoolsMessageStr = localStorage.getItem(__FEDERATION_DEVTOOLS__);
80
- if (devtoolsMessageStr) {
81
- try {
82
- return JSON.parse(devtoolsMessageStr);
83
- } catch (e) {
84
- console.debug("Fast Refresh Plugin Error: ", e);
85
- }
86
- }
87
- return null;
88
- };
89
- const devtoolsMessage = getDevtoolsMessage();
90
- if ((devtoolsMessage == null ? void 0 : devtoolsMessage[__ENABLE_FAST_REFRESH__]) && (devtoolsMessage == null ? void 0 : devtoolsMessage[__EAGER_SHARE__])) {
91
- const [_name, version] = devtoolsMessage[__EAGER_SHARE__];
92
- fetchAndExecuteUmdSync(getUnpkgUrl("react", version));
93
- fetchAndExecuteUmdSync(getUnpkgUrl("react-dom", version));
94
- }
95
- const fastRefreshPlugin = () => {
96
- return {
97
- name: "mf-fast-refresh-plugin",
98
- beforeInit(_a2) {
99
- var _b = _a2, { userOptions } = _b, args = __objRest(_b, ["userOptions"]);
100
- const shareInfo = userOptions.shared;
101
- const twinsShareInfo = args.shareInfo;
102
- let enableFastRefresh = false;
103
- let devtoolsMessage2 = {};
85
+ devtoolsMessage2[__EAGER_SHARE__] = [pkgName, version, mergedScopes];
86
+ return {
87
+ shouldReload: !existing || existing.version !== version
88
+ };
89
+ };
90
+ const requestUmdSourceSync = (url) => {
91
+ try {
92
+ const response = new XMLHttpRequest();
93
+ response.open("GET", url, false);
94
+ response.overrideMimeType("text/plain");
95
+ response.send();
96
+ if (response.status === 200) {
97
+ return response.responseText;
98
+ }
99
+ throw new Error(
100
+ `Failed to load module from ${url}: HTTP ${response.status}`
101
+ );
102
+ } catch (error) {
103
+ throw new Error(`Failed to fetch module from ${url}: ${error.message}`);
104
+ }
105
+ };
106
+ const requestUmdSource = (url) => new Promise((resolve, reject) => {
107
+ try {
108
+ const response = new XMLHttpRequest();
109
+ response.open("GET", url, true);
110
+ response.overrideMimeType("text/plain");
111
+ response.onload = () => {
112
+ if (response.status === 200) {
113
+ resolve(response.responseText);
114
+ return;
115
+ }
116
+ reject(
117
+ new Error(
118
+ `Failed to load module from ${url}: HTTP ${response.status}`
119
+ )
120
+ );
121
+ };
122
+ response.onerror = () => {
123
+ reject(new Error(`Failed to fetch module from ${url}`));
124
+ };
125
+ response.send();
126
+ } catch (error) {
127
+ reject(new Error(`Failed to fetch module from ${url}: ${error.message}`));
128
+ }
129
+ });
130
+ const createUmdSandbox = (pkgName, scopes) => {
131
+ const sandboxTarget = /* @__PURE__ */ Object.create(null);
132
+ const sandbox = new Proxy(sandboxTarget, {
133
+ get(target, key) {
134
+ if (typeof key === "symbol") {
135
+ return Reflect.get(target, key);
136
+ }
137
+ if (key in target) {
138
+ return target[key];
139
+ }
140
+ const value = window[key];
141
+ return typeof value === "function" ? value.bind(window) : value;
142
+ },
143
+ set(target, key, value) {
144
+ target[key] = value;
145
+ return true;
146
+ },
147
+ has(target, key) {
148
+ return key in target || key in window;
149
+ }
150
+ });
151
+ sandboxTarget.window = sandbox;
152
+ sandboxTarget.self = sandbox;
153
+ sandboxTarget.globalThis = sandbox;
154
+ sandboxTarget.global = sandbox;
155
+ sandboxTarget.document = window.document;
156
+ if (pkgName === "react-dom") {
157
+ sandboxTarget.React = getScopeGlobal("react", scopes);
158
+ }
159
+ return sandbox;
160
+ };
161
+ const executeUmdModule = (scriptContent, pkgName, scopes) => {
162
+ const sandbox = createUmdSandbox(pkgName, scopes);
163
+ const moduleFunction = new Function(
164
+ "window",
165
+ "self",
166
+ "globalThis",
167
+ "global",
168
+ "document",
169
+ "exports",
170
+ "module",
171
+ "define",
172
+ "require",
173
+ scriptContent
174
+ );
175
+ moduleFunction.call(
176
+ sandbox,
177
+ sandbox,
178
+ sandbox,
179
+ sandbox,
180
+ sandbox,
181
+ sandbox.document,
182
+ void 0,
183
+ void 0,
184
+ void 0,
185
+ void 0
186
+ );
187
+ return sandbox[getDefaultGlobalKey(pkgName)];
188
+ };
189
+ const loadUmdModuleSync = (pkgName, version, scopes) => executeUmdModule(
190
+ requestUmdSourceSync(getUnpkgUrl(pkgName, version)),
191
+ pkgName,
192
+ scopes
193
+ );
194
+ const loadUmdModule = (pkgName, version, scopes) => __async(exports, null, function* () {
195
+ return executeUmdModule(
196
+ yield requestUmdSource(getUnpkgUrl(pkgName, version)),
197
+ pkgName,
198
+ scopes
199
+ );
200
+ });
201
+ const getDevtoolsMessage = () => {
104
202
  const devtoolsMessageStr = localStorage.getItem(__FEDERATION_DEVTOOLS__);
105
203
  if (devtoolsMessageStr) {
106
204
  try {
107
- devtoolsMessage2 = JSON.parse(devtoolsMessageStr);
108
- enableFastRefresh = devtoolsMessage2 == null ? void 0 : devtoolsMessage2[__ENABLE_FAST_REFRESH__];
205
+ return JSON.parse(devtoolsMessageStr);
109
206
  } catch (e) {
110
207
  console.debug("Fast Refresh Plugin Error: ", e);
111
208
  }
112
209
  }
113
- if (!enableFastRefresh) {
114
- return __spreadValues({
115
- userOptions
116
- }, args);
117
- }
118
- if (shareInfo && isObject(shareInfo)) {
119
- let orderResolve;
120
- const orderPromise = new Promise((resolve) => {
121
- orderResolve = resolve;
122
- });
123
- Object.keys(shareInfo).forEach((share) => __async(this, null, function* () {
124
- const sharedArr = Array.isArray(shareInfo[share]) ? shareInfo[share] : [shareInfo[share]];
125
- let twinsSharedArr;
126
- if (twinsShareInfo) {
127
- twinsSharedArr = Array.isArray(twinsShareInfo[share]) ? twinsShareInfo[share] : [twinsShareInfo[share]];
210
+ return null;
211
+ };
212
+ const devtoolsMessage = getDevtoolsMessage();
213
+ const eagerShareInfo = getEagerShareInfo(devtoolsMessage == null ? void 0 : devtoolsMessage[__EAGER_SHARE__]);
214
+ if ((devtoolsMessage == null ? void 0 : devtoolsMessage[__ENABLE_FAST_REFRESH__]) && eagerShareInfo) {
215
+ const { version, scopes } = eagerShareInfo;
216
+ setScopeGlobals("react", scopes, loadUmdModuleSync("react", version, scopes));
217
+ setScopeGlobals(
218
+ "react-dom",
219
+ scopes,
220
+ loadUmdModuleSync("react-dom", version, scopes)
221
+ );
222
+ }
223
+ const fastRefreshPlugin = () => {
224
+ let orderResolve;
225
+ const orderPromise = new Promise((resolve) => {
226
+ orderResolve = resolve;
227
+ });
228
+ return {
229
+ name: "mf-fast-refresh-plugin",
230
+ beforeRegisterShare(args) {
231
+ var _a2;
232
+ const { pkgName, shared } = args;
233
+ if (!SUPPORT_PKGS.includes(pkgName)) {
234
+ return args;
128
235
  }
129
- sharedArr.forEach((shared, idx) => {
130
- var _a3;
131
- if (!SUPPORT_PKGS.includes(share)) {
132
- return;
236
+ const supportPkgName = pkgName;
237
+ const shareScopes = getShareScopes(shared.scope);
238
+ let enableFastRefresh = false;
239
+ let devtoolsMessage2 = {};
240
+ const devtoolsMessageStr = localStorage.getItem(__FEDERATION_DEVTOOLS__);
241
+ if (devtoolsMessageStr) {
242
+ try {
243
+ devtoolsMessage2 = JSON.parse(devtoolsMessageStr);
244
+ enableFastRefresh = devtoolsMessage2 == null ? void 0 : devtoolsMessage2[__ENABLE_FAST_REFRESH__];
245
+ } catch (e) {
246
+ console.debug("Fast Refresh Plugin Error: ", e);
133
247
  }
134
- if ((_a3 = shared.shareConfig) == null ? void 0 : _a3.eager) {
135
- if (!(devtoolsMessage2 == null ? void 0 : devtoolsMessage2[__EAGER_SHARE__])) {
136
- const eagerShare = [];
137
- eagerShare.push(share, shared.version);
138
- devtoolsMessage2[__EAGER_SHARE__] = eagerShare;
139
- localStorage.setItem(
140
- __FEDERATION_DEVTOOLS__,
141
- JSON.stringify(devtoolsMessage2)
142
- );
248
+ }
249
+ if (!enableFastRefresh) {
250
+ return args;
251
+ }
252
+ if (((_a2 = shared.shareConfig) == null ? void 0 : _a2.eager) || shared.lib) {
253
+ if (!(devtoolsMessage2 == null ? void 0 : devtoolsMessage2[__EAGER_SHARE__])) {
254
+ const eagerShareInfo2 = updateEagerShareInfo(
255
+ devtoolsMessage2,
256
+ pkgName,
257
+ shared.version,
258
+ shareScopes
259
+ );
260
+ localStorage.setItem(
261
+ __FEDERATION_DEVTOOLS__,
262
+ JSON.stringify(devtoolsMessage2)
263
+ );
264
+ if (eagerShareInfo2.shouldReload) {
143
265
  window.location.reload();
144
266
  }
145
- if (share === "react-dom") {
146
- shared.lib = () => window.ReactDOM;
147
- }
148
- if (share === "react") {
149
- shared.lib = () => window.React;
150
- }
151
- return;
267
+ } else {
268
+ updateEagerShareInfo(
269
+ devtoolsMessage2,
270
+ pkgName,
271
+ shared.version,
272
+ shareScopes
273
+ );
274
+ localStorage.setItem(
275
+ __FEDERATION_DEVTOOLS__,
276
+ JSON.stringify(devtoolsMessage2)
277
+ );
278
+ }
279
+ if (pkgName === "react-dom") {
280
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
152
281
  }
153
- let get;
154
- if (share === "react") {
155
- get = () => loadScript(getUnpkgUrl(share, shared.version), {
156
- attrs: {
157
- defer: false,
158
- async: false,
159
- "data-mf-injected": "true"
282
+ if (pkgName === "react") {
283
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
284
+ }
285
+ return args;
286
+ }
287
+ let get;
288
+ if (pkgName === "react") {
289
+ get = () => loadUmdModule(supportPkgName, shared.version, shareScopes).then((moduleValue) => {
290
+ setScopeGlobals(supportPkgName, shareScopes, moduleValue);
291
+ return moduleValue;
292
+ }).then(() => {
293
+ orderResolve();
294
+ });
295
+ }
296
+ if (pkgName === "react-dom") {
297
+ get = () => orderPromise.then(
298
+ () => loadUmdModule(supportPkgName, shared.version, shareScopes)
299
+ ).then((result) => {
300
+ setScopeGlobals(supportPkgName, shareScopes, result);
301
+ return result;
302
+ });
303
+ }
304
+ if (typeof get === "function") {
305
+ const finalGet = get;
306
+ if (pkgName === "react") {
307
+ shared.get = () => __async(this, null, function* () {
308
+ if (!getScopeGlobal(supportPkgName, shareScopes)) {
309
+ yield finalGet();
310
+ console.warn(
311
+ "[Module Federation HMR]: You are using Module Federation Devtools to debug online host, it will cause your project load Dev mode React and ReactDOM. If not in this mode, please disable it in Module Federation Devtools"
312
+ );
160
313
  }
161
- }).then(() => {
162
- orderResolve();
314
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
315
+ return () => getScopeGlobal(supportPkgName, shareScopes);
163
316
  });
164
317
  }
165
- if (share === "react-dom") {
166
- get = () => orderPromise.then(
167
- () => loadScript(getUnpkgUrl(share, shared.version), {
168
- attrs: { defer: true, async: false }
169
- })
170
- );
171
- }
172
- if (typeof get === "function") {
173
- if (share === "react") {
174
- shared.get = () => __async(this, null, function* () {
175
- if (!window.React) {
176
- yield get();
177
- console.warn(
178
- "[Module Federation HMR]: You are using Module Federation Devtools to debug online host, it will cause your project load Dev mode React and ReactDOM. If not in this mode, please disable it in Module Federation Devtools"
179
- );
180
- }
181
- shared.lib = () => window.React;
182
- return () => window.React;
183
- });
184
- }
185
- if (share === "react-dom") {
186
- shared.get = () => __async(this, null, function* () {
187
- if (!window.ReactDOM) {
188
- yield get();
189
- }
190
- shared.lib = () => window.ReactDOM;
191
- return () => window.ReactDOM;
192
- });
193
- }
194
- if (twinsShareInfo) {
195
- twinsSharedArr[idx].get = shared.get;
196
- }
318
+ if (pkgName === "react-dom") {
319
+ shared.get = () => __async(this, null, function* () {
320
+ if (!getScopeGlobal(supportPkgName, shareScopes)) {
321
+ yield finalGet();
322
+ }
323
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
324
+ return () => getScopeGlobal(supportPkgName, shareScopes);
325
+ });
197
326
  }
198
- });
199
- }));
200
- return __spreadValues({
201
- userOptions
202
- }, args);
203
- } else {
204
- return __spreadValues({
205
- userOptions
206
- }, args);
207
- }
327
+ }
328
+ return args;
329
+ }
330
+ };
331
+ };
332
+ if (!(window == null ? void 0 : window.__FEDERATION__)) {
333
+ definePropertyGlobalVal(window, "__FEDERATION__", {});
334
+ definePropertyGlobalVal(window, "__VMOK__", window.__FEDERATION__);
208
335
  }
209
- };
210
- };
211
- if (!(window == null ? void 0 : window.__FEDERATION__)) {
212
- definePropertyGlobalVal(window, "__FEDERATION__", {});
213
- definePropertyGlobalVal(window, "__VMOK__", window.__FEDERATION__);
214
- }
215
- if (!(window == null ? void 0 : window.__FEDERATION__.__GLOBAL_PLUGIN__)) {
216
- window.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
217
- }
218
- (_a = window.__FEDERATION__.__GLOBAL_PLUGIN__) == null ? void 0 : _a.push(fastRefreshPlugin());
336
+ if (!(window == null ? void 0 : window.__FEDERATION__.__GLOBAL_PLUGIN__)) {
337
+ window.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
338
+ }
339
+ (_a = window.__FEDERATION__.__GLOBAL_PLUGIN__) == null ? void 0 : _a.push(fastRefreshPlugin());
340
+ }
341
+ });
342
+ export default require_fast_refresh();
@@ -1,7 +1,7 @@
1
1
  var _a;
2
2
  import runtimeHelpers from "@module-federation/runtime/helpers";
3
+ import { MODULE_DEVTOOL_IDENTIFIER } from "@module-federation/sdk";
3
4
  import { definePropertyGlobalVal } from "../sdk";
4
- import { __FEDERATION_DEVTOOLS__ } from "../../template";
5
5
  const chromeOverrideRemotesPlugin = function() {
6
6
  return {
7
7
  name: "mf-chrome-devtools-override-remotes-plugin",
@@ -9,7 +9,7 @@ const chromeOverrideRemotesPlugin = function() {
9
9
  try {
10
10
  const { remote } = args;
11
11
  const overrideRemote = runtimeHelpers.global.nativeGlobal.localStorage.getItem(
12
- __FEDERATION_DEVTOOLS__
12
+ MODULE_DEVTOOL_IDENTIFIER
13
13
  );
14
14
  if (!overrideRemote) {
15
15
  return args;
@@ -1,32 +1,4 @@
1
1
  "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
6
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
- var __spreadValues = (a, b) => {
8
- for (var prop in b || (b = {}))
9
- if (__hasOwnProp.call(b, prop))
10
- __defNormalProp(a, prop, b[prop]);
11
- if (__getOwnPropSymbols)
12
- for (var prop of __getOwnPropSymbols(b)) {
13
- if (__propIsEnum.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- }
16
- return a;
17
- };
18
- var __objRest = (source, exclude) => {
19
- var target = {};
20
- for (var prop in source)
21
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
22
- target[prop] = source[prop];
23
- if (source != null && __getOwnPropSymbols)
24
- for (var prop of __getOwnPropSymbols(source)) {
25
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
26
- target[prop] = source[prop];
27
- }
28
- return target;
29
- };
30
2
  var __async = (__this, __arguments, generator) => {
31
3
  return new Promise((resolve, reject) => {
32
4
  var fulfilled = (value) => {
@@ -47,31 +19,176 @@ var __async = (__this, __arguments, generator) => {
47
19
  step((generator = generator.apply(__this, __arguments)).next());
48
20
  });
49
21
  };
50
- var import_sdk = require("@module-federation/sdk");
51
22
  var import__ = require("../index");
52
- var import_sdk2 = require("../sdk");
23
+ var import_sdk = require("../sdk");
53
24
  var import_constant = require("../../template/constant");
54
25
  var _a;
55
26
  const SUPPORT_PKGS = ["react", "react-dom"];
56
- const fetchAndExecuteUmdSync = (url) => {
27
+ const DEFAULT_SHARE_SCOPE = "default";
28
+ const DEFAULT_GLOBAL_KEY_MAP = {
29
+ react: "React",
30
+ "react-dom": "ReactDOM"
31
+ };
32
+ const sanitizeWindowKey = (value) => value.replace(/[^a-zA-Z0-9_$]/g, "_");
33
+ const getShareScopes = (scope) => Array.isArray(scope) && scope.length ? scope : [DEFAULT_SHARE_SCOPE];
34
+ const getDefaultGlobalKey = (pkgName) => DEFAULT_GLOBAL_KEY_MAP[pkgName];
35
+ const getScopedGlobalKey = (scope, pkgName) => `${sanitizeWindowKey(scope)}_${sanitizeWindowKey(pkgName)}`;
36
+ const getWindowValue = (key) => window[key];
37
+ const setWindowValue = (key, value) => {
38
+ window[key] = value;
39
+ };
40
+ const setScopeGlobals = (pkgName, scopes, source) => {
41
+ if (!source) {
42
+ return source;
43
+ }
44
+ scopes.forEach((scope) => {
45
+ setWindowValue(getScopedGlobalKey(scope, pkgName), source);
46
+ });
47
+ return source;
48
+ };
49
+ const getScopeGlobal = (pkgName, scopes) => {
50
+ for (const scope of scopes) {
51
+ const scopeGlobal = getWindowValue(getScopedGlobalKey(scope, pkgName));
52
+ if (scopeGlobal) {
53
+ return scopeGlobal;
54
+ }
55
+ }
56
+ return void 0;
57
+ };
58
+ const getEagerShareInfo = (eagerShare) => {
59
+ if (!Array.isArray(eagerShare) || eagerShare.length < 2) {
60
+ return null;
61
+ }
62
+ const [, version, scopes] = eagerShare;
63
+ if (typeof version !== "string") {
64
+ return null;
65
+ }
66
+ return {
67
+ version,
68
+ scopes: getShareScopes(scopes)
69
+ };
70
+ };
71
+ const updateEagerShareInfo = (devtoolsMessage2, pkgName, version, scopes) => {
72
+ const existing = getEagerShareInfo(devtoolsMessage2[import_constant.__EAGER_SHARE__]);
73
+ const mergedScopes = Array.from(
74
+ /* @__PURE__ */ new Set([...(existing == null ? void 0 : existing.scopes) || [], ...scopes])
75
+ );
76
+ devtoolsMessage2[import_constant.__EAGER_SHARE__] = [pkgName, version, mergedScopes];
77
+ return {
78
+ shouldReload: !existing || existing.version !== version
79
+ };
80
+ };
81
+ const requestUmdSourceSync = (url) => {
57
82
  try {
58
83
  const response = new XMLHttpRequest();
59
84
  response.open("GET", url, false);
60
85
  response.overrideMimeType("text/plain");
61
86
  response.send();
62
87
  if (response.status === 200) {
63
- const scriptContent = response.responseText;
64
- const moduleFunction = new Function(scriptContent);
65
- return moduleFunction(window);
66
- } else {
67
- throw new Error(
68
- `Failed to load module from ${url}: HTTP ${response.status}`
69
- );
88
+ return response.responseText;
70
89
  }
90
+ throw new Error(
91
+ `Failed to load module from ${url}: HTTP ${response.status}`
92
+ );
71
93
  } catch (error) {
72
94
  throw new Error(`Failed to fetch module from ${url}: ${error.message}`);
73
95
  }
74
96
  };
97
+ const requestUmdSource = (url) => new Promise((resolve, reject) => {
98
+ try {
99
+ const response = new XMLHttpRequest();
100
+ response.open("GET", url, true);
101
+ response.overrideMimeType("text/plain");
102
+ response.onload = () => {
103
+ if (response.status === 200) {
104
+ resolve(response.responseText);
105
+ return;
106
+ }
107
+ reject(
108
+ new Error(
109
+ `Failed to load module from ${url}: HTTP ${response.status}`
110
+ )
111
+ );
112
+ };
113
+ response.onerror = () => {
114
+ reject(new Error(`Failed to fetch module from ${url}`));
115
+ };
116
+ response.send();
117
+ } catch (error) {
118
+ reject(new Error(`Failed to fetch module from ${url}: ${error.message}`));
119
+ }
120
+ });
121
+ const createUmdSandbox = (pkgName, scopes) => {
122
+ const sandboxTarget = /* @__PURE__ */ Object.create(null);
123
+ const sandbox = new Proxy(sandboxTarget, {
124
+ get(target, key) {
125
+ if (typeof key === "symbol") {
126
+ return Reflect.get(target, key);
127
+ }
128
+ if (key in target) {
129
+ return target[key];
130
+ }
131
+ const value = window[key];
132
+ return typeof value === "function" ? value.bind(window) : value;
133
+ },
134
+ set(target, key, value) {
135
+ target[key] = value;
136
+ return true;
137
+ },
138
+ has(target, key) {
139
+ return key in target || key in window;
140
+ }
141
+ });
142
+ sandboxTarget.window = sandbox;
143
+ sandboxTarget.self = sandbox;
144
+ sandboxTarget.globalThis = sandbox;
145
+ sandboxTarget.global = sandbox;
146
+ sandboxTarget.document = window.document;
147
+ if (pkgName === "react-dom") {
148
+ sandboxTarget.React = getScopeGlobal("react", scopes);
149
+ }
150
+ return sandbox;
151
+ };
152
+ const executeUmdModule = (scriptContent, pkgName, scopes) => {
153
+ const sandbox = createUmdSandbox(pkgName, scopes);
154
+ const moduleFunction = new Function(
155
+ "window",
156
+ "self",
157
+ "globalThis",
158
+ "global",
159
+ "document",
160
+ "exports",
161
+ "module",
162
+ "define",
163
+ "require",
164
+ scriptContent
165
+ );
166
+ moduleFunction.call(
167
+ sandbox,
168
+ sandbox,
169
+ sandbox,
170
+ sandbox,
171
+ sandbox,
172
+ sandbox.document,
173
+ void 0,
174
+ void 0,
175
+ void 0,
176
+ void 0
177
+ );
178
+ return sandbox[getDefaultGlobalKey(pkgName)];
179
+ };
180
+ const loadUmdModuleSync = (pkgName, version, scopes) => executeUmdModule(
181
+ requestUmdSourceSync((0, import__.getUnpkgUrl)(pkgName, version)),
182
+ pkgName,
183
+ scopes
184
+ );
185
+ const loadUmdModule = (pkgName, version, scopes) => __async(exports, null, function* () {
186
+ return executeUmdModule(
187
+ yield requestUmdSource((0, import__.getUnpkgUrl)(pkgName, version)),
188
+ pkgName,
189
+ scopes
190
+ );
191
+ });
75
192
  const getDevtoolsMessage = () => {
76
193
  const devtoolsMessageStr = localStorage.getItem(import_constant.__FEDERATION_DEVTOOLS__);
77
194
  if (devtoolsMessageStr) {
@@ -84,18 +201,31 @@ const getDevtoolsMessage = () => {
84
201
  return null;
85
202
  };
86
203
  const devtoolsMessage = getDevtoolsMessage();
87
- if ((devtoolsMessage == null ? void 0 : devtoolsMessage[import_constant.__ENABLE_FAST_REFRESH__]) && (devtoolsMessage == null ? void 0 : devtoolsMessage[import_constant.__EAGER_SHARE__])) {
88
- const [_name, version] = devtoolsMessage[import_constant.__EAGER_SHARE__];
89
- fetchAndExecuteUmdSync((0, import__.getUnpkgUrl)("react", version));
90
- fetchAndExecuteUmdSync((0, import__.getUnpkgUrl)("react-dom", version));
204
+ const eagerShareInfo = getEagerShareInfo(devtoolsMessage == null ? void 0 : devtoolsMessage[import_constant.__EAGER_SHARE__]);
205
+ if ((devtoolsMessage == null ? void 0 : devtoolsMessage[import_constant.__ENABLE_FAST_REFRESH__]) && eagerShareInfo) {
206
+ const { version, scopes } = eagerShareInfo;
207
+ setScopeGlobals("react", scopes, loadUmdModuleSync("react", version, scopes));
208
+ setScopeGlobals(
209
+ "react-dom",
210
+ scopes,
211
+ loadUmdModuleSync("react-dom", version, scopes)
212
+ );
91
213
  }
92
214
  const fastRefreshPlugin = () => {
215
+ let orderResolve;
216
+ const orderPromise = new Promise((resolve) => {
217
+ orderResolve = resolve;
218
+ });
93
219
  return {
94
220
  name: "mf-fast-refresh-plugin",
95
- beforeInit(_a2) {
96
- var _b = _a2, { userOptions } = _b, args = __objRest(_b, ["userOptions"]);
97
- const shareInfo = userOptions.shared;
98
- const twinsShareInfo = args.shareInfo;
221
+ beforeRegisterShare(args) {
222
+ var _a2;
223
+ const { pkgName, shared } = args;
224
+ if (!SUPPORT_PKGS.includes(pkgName)) {
225
+ return args;
226
+ }
227
+ const supportPkgName = pkgName;
228
+ const shareScopes = getShareScopes(shared.scope);
99
229
  let enableFastRefresh = false;
100
230
  let devtoolsMessage2 = {};
101
231
  const devtoolsMessageStr = localStorage.getItem(import_constant.__FEDERATION_DEVTOOLS__);
@@ -108,106 +238,91 @@ const fastRefreshPlugin = () => {
108
238
  }
109
239
  }
110
240
  if (!enableFastRefresh) {
111
- return __spreadValues({
112
- userOptions
113
- }, args);
241
+ return args;
114
242
  }
115
- if (shareInfo && (0, import__.isObject)(shareInfo)) {
116
- let orderResolve;
117
- const orderPromise = new Promise((resolve) => {
118
- orderResolve = resolve;
119
- });
120
- Object.keys(shareInfo).forEach((share) => __async(this, null, function* () {
121
- const sharedArr = Array.isArray(shareInfo[share]) ? shareInfo[share] : [shareInfo[share]];
122
- let twinsSharedArr;
123
- if (twinsShareInfo) {
124
- twinsSharedArr = Array.isArray(twinsShareInfo[share]) ? twinsShareInfo[share] : [twinsShareInfo[share]];
243
+ if (((_a2 = shared.shareConfig) == null ? void 0 : _a2.eager) || shared.lib) {
244
+ if (!(devtoolsMessage2 == null ? void 0 : devtoolsMessage2[import_constant.__EAGER_SHARE__])) {
245
+ const eagerShareInfo2 = updateEagerShareInfo(
246
+ devtoolsMessage2,
247
+ pkgName,
248
+ shared.version,
249
+ shareScopes
250
+ );
251
+ localStorage.setItem(
252
+ import_constant.__FEDERATION_DEVTOOLS__,
253
+ JSON.stringify(devtoolsMessage2)
254
+ );
255
+ if (eagerShareInfo2.shouldReload) {
256
+ window.location.reload();
125
257
  }
126
- sharedArr.forEach((shared, idx) => {
127
- var _a3;
128
- if (!SUPPORT_PKGS.includes(share)) {
129
- return;
130
- }
131
- if ((_a3 = shared.shareConfig) == null ? void 0 : _a3.eager) {
132
- if (!(devtoolsMessage2 == null ? void 0 : devtoolsMessage2[import_constant.__EAGER_SHARE__])) {
133
- const eagerShare = [];
134
- eagerShare.push(share, shared.version);
135
- devtoolsMessage2[import_constant.__EAGER_SHARE__] = eagerShare;
136
- localStorage.setItem(
137
- import_constant.__FEDERATION_DEVTOOLS__,
138
- JSON.stringify(devtoolsMessage2)
139
- );
140
- window.location.reload();
141
- }
142
- if (share === "react-dom") {
143
- shared.lib = () => window.ReactDOM;
144
- }
145
- if (share === "react") {
146
- shared.lib = () => window.React;
147
- }
148
- return;
149
- }
150
- let get;
151
- if (share === "react") {
152
- get = () => (0, import_sdk.loadScript)((0, import__.getUnpkgUrl)(share, shared.version), {
153
- attrs: {
154
- defer: false,
155
- async: false,
156
- "data-mf-injected": "true"
157
- }
158
- }).then(() => {
159
- orderResolve();
160
- });
161
- }
162
- if (share === "react-dom") {
163
- get = () => orderPromise.then(
164
- () => (0, import_sdk.loadScript)((0, import__.getUnpkgUrl)(share, shared.version), {
165
- attrs: { defer: true, async: false }
166
- })
258
+ } else {
259
+ updateEagerShareInfo(
260
+ devtoolsMessage2,
261
+ pkgName,
262
+ shared.version,
263
+ shareScopes
264
+ );
265
+ localStorage.setItem(
266
+ import_constant.__FEDERATION_DEVTOOLS__,
267
+ JSON.stringify(devtoolsMessage2)
268
+ );
269
+ }
270
+ if (pkgName === "react-dom") {
271
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
272
+ }
273
+ if (pkgName === "react") {
274
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
275
+ }
276
+ return args;
277
+ }
278
+ let get;
279
+ if (pkgName === "react") {
280
+ get = () => loadUmdModule(supportPkgName, shared.version, shareScopes).then((moduleValue) => {
281
+ setScopeGlobals(supportPkgName, shareScopes, moduleValue);
282
+ return moduleValue;
283
+ }).then(() => {
284
+ orderResolve();
285
+ });
286
+ }
287
+ if (pkgName === "react-dom") {
288
+ get = () => orderPromise.then(
289
+ () => loadUmdModule(supportPkgName, shared.version, shareScopes)
290
+ ).then((result) => {
291
+ setScopeGlobals(supportPkgName, shareScopes, result);
292
+ return result;
293
+ });
294
+ }
295
+ if (typeof get === "function") {
296
+ const finalGet = get;
297
+ if (pkgName === "react") {
298
+ shared.get = () => __async(this, null, function* () {
299
+ if (!getScopeGlobal(supportPkgName, shareScopes)) {
300
+ yield finalGet();
301
+ console.warn(
302
+ "[Module Federation HMR]: You are using Module Federation Devtools to debug online host, it will cause your project load Dev mode React and ReactDOM. If not in this mode, please disable it in Module Federation Devtools"
167
303
  );
168
304
  }
169
- if (typeof get === "function") {
170
- if (share === "react") {
171
- shared.get = () => __async(this, null, function* () {
172
- if (!window.React) {
173
- yield get();
174
- console.warn(
175
- "[Module Federation HMR]: You are using Module Federation Devtools to debug online host, it will cause your project load Dev mode React and ReactDOM. If not in this mode, please disable it in Module Federation Devtools"
176
- );
177
- }
178
- shared.lib = () => window.React;
179
- return () => window.React;
180
- });
181
- }
182
- if (share === "react-dom") {
183
- shared.get = () => __async(this, null, function* () {
184
- if (!window.ReactDOM) {
185
- yield get();
186
- }
187
- shared.lib = () => window.ReactDOM;
188
- return () => window.ReactDOM;
189
- });
190
- }
191
- if (twinsShareInfo) {
192
- twinsSharedArr[idx].get = shared.get;
193
- }
305
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
306
+ return () => getScopeGlobal(supportPkgName, shareScopes);
307
+ });
308
+ }
309
+ if (pkgName === "react-dom") {
310
+ shared.get = () => __async(this, null, function* () {
311
+ if (!getScopeGlobal(supportPkgName, shareScopes)) {
312
+ yield finalGet();
194
313
  }
314
+ shared.lib = () => getScopeGlobal(supportPkgName, shareScopes);
315
+ return () => getScopeGlobal(supportPkgName, shareScopes);
195
316
  });
196
- }));
197
- return __spreadValues({
198
- userOptions
199
- }, args);
200
- } else {
201
- return __spreadValues({
202
- userOptions
203
- }, args);
317
+ }
204
318
  }
319
+ return args;
205
320
  }
206
321
  };
207
322
  };
208
323
  if (!(window == null ? void 0 : window.__FEDERATION__)) {
209
- (0, import_sdk2.definePropertyGlobalVal)(window, "__FEDERATION__", {});
210
- (0, import_sdk2.definePropertyGlobalVal)(window, "__VMOK__", window.__FEDERATION__);
324
+ (0, import_sdk.definePropertyGlobalVal)(window, "__FEDERATION__", {});
325
+ (0, import_sdk.definePropertyGlobalVal)(window, "__VMOK__", window.__FEDERATION__);
211
326
  }
212
327
  if (!(window == null ? void 0 : window.__FEDERATION__.__GLOBAL_PLUGIN__)) {
213
328
  window.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
@@ -22,8 +22,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  var import_helpers = __toESM(require("@module-federation/runtime/helpers"));
25
- var import_sdk = require("../sdk");
26
- var import_template = require("../../template");
25
+ var import_sdk = require("@module-federation/sdk");
26
+ var import_sdk2 = require("../sdk");
27
27
  var _a;
28
28
  const chromeOverrideRemotesPlugin = function() {
29
29
  return {
@@ -32,7 +32,7 @@ const chromeOverrideRemotesPlugin = function() {
32
32
  try {
33
33
  const { remote } = args;
34
34
  const overrideRemote = import_helpers.default.global.nativeGlobal.localStorage.getItem(
35
- import_template.__FEDERATION_DEVTOOLS__
35
+ import_sdk.MODULE_DEVTOOL_IDENTIFIER
36
36
  );
37
37
  if (!overrideRemote) {
38
38
  return args;
@@ -56,8 +56,8 @@ const chromeOverrideRemotesPlugin = function() {
56
56
  };
57
57
  };
58
58
  if (!(window == null ? void 0 : window.__FEDERATION__)) {
59
- (0, import_sdk.definePropertyGlobalVal)(window, "__FEDERATION__", {});
60
- (0, import_sdk.definePropertyGlobalVal)(window, "__VMOK__", window.__FEDERATION__);
59
+ (0, import_sdk2.definePropertyGlobalVal)(window, "__FEDERATION__", {});
60
+ (0, import_sdk2.definePropertyGlobalVal)(window, "__VMOK__", window.__FEDERATION__);
61
61
  }
62
62
  if (!(window == null ? void 0 : window.__FEDERATION__.__GLOBAL_PLUGIN__)) {
63
63
  window.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/devtools",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -47,7 +47,7 @@
47
47
  "echarts-for-react": "3.0.5",
48
48
  "i18next": "23.0.0",
49
49
  "react-i18next": "15.0.0",
50
- "@module-federation/sdk": "2.3.2"
50
+ "@module-federation/sdk": "2.4.0"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "react": "^18 || ^19",
@@ -82,7 +82,7 @@
82
82
  "typescript": "5.9.3",
83
83
  "rimraf": "~6.0.1",
84
84
  "vitest": "1.2.2",
85
- "@module-federation/runtime": "2.3.2"
85
+ "@module-federation/runtime": "2.4.0"
86
86
  },
87
87
  "scripts": {
88
88
  "build:storybook": "storybook build",