@fulgurjs/federation 2.0.2 → 2.1.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.
- package/CHANGELOG.md +27 -0
- package/README.md +68 -9
- package/client.d.ts +17 -1
- package/dist/{chunk-UDLQALHC.js → chunk-RP6HNIQT.js} +1 -1
- package/dist/cli.js +147 -3
- package/dist/index.cjs +536 -86
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +538 -86
- package/dist/runtime.js +3 -3
- package/dist/vue.cjs +170 -40
- package/dist/vue.js +171 -41
- package/docs/P5-vite7-8/345/205/274/345/256/271/347/237/251/351/230/265.md +4 -2
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RUNTIME_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RP6HNIQT.js";
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
|
-
import
|
|
6
|
+
import path6 from "path";
|
|
7
7
|
import { createRequire as createRequire2 } from "module";
|
|
8
8
|
|
|
9
9
|
// src/options.ts
|
|
10
10
|
import { createRequire } from "module";
|
|
11
11
|
import fs from "fs";
|
|
12
12
|
import path from "path";
|
|
13
|
+
|
|
14
|
+
// src/dev-cors.ts
|
|
15
|
+
function normalizeDevCorsOrigins(input) {
|
|
16
|
+
if (input === void 0 || input === "*") return { ok: true, value: input };
|
|
17
|
+
if (!Array.isArray(input) || input.length === 0) {
|
|
18
|
+
return { ok: false, reason: '\u5FC5\u987B\u662F "*" \u6216\u975E\u7A7A\u6570\u7EC4' };
|
|
19
|
+
}
|
|
20
|
+
for (const item of input) {
|
|
21
|
+
if (typeof item !== "string" || !/^https?:\/\/[^/]+$/i.test(item)) {
|
|
22
|
+
return { ok: false, reason: `\u6765\u6E90\u5FC5\u987B\u662F http(s)://host[:port] \u5F62\u6001\uFF08\u65E0\u8DEF\u5F84\uFF09\uFF0Cgot: ${JSON.stringify(item)}` };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return { ok: true, value: input };
|
|
26
|
+
}
|
|
27
|
+
function corsHeadersFor(origin, allowed) {
|
|
28
|
+
if (allowed === void 0 || allowed === "*") {
|
|
29
|
+
return { "Access-Control-Allow-Origin": "*" };
|
|
30
|
+
}
|
|
31
|
+
if (!origin || !allowed.includes(origin)) return {};
|
|
32
|
+
return { "Access-Control-Allow-Origin": origin, Vary: "Origin" };
|
|
33
|
+
}
|
|
34
|
+
function isNonLoopbackHost(host) {
|
|
35
|
+
if (host === void 0 || host === false) return false;
|
|
36
|
+
const h = host === true ? "0.0.0.0" : String(host);
|
|
37
|
+
return !["localhost", "127.0.0.1", "::1", "[::1]"].includes(h.toLowerCase());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/options.ts
|
|
13
41
|
var DEFAULT_FILENAME = "fulgurjs-remoteEntry.js";
|
|
14
42
|
var RUNTIME_VIRTUAL_ID = "virtual:fulgurjs-runtime";
|
|
15
43
|
var RUNTIME_PROXY_VIRTUAL_ID = "virtual:fulgurjs-runtime-proxy";
|
|
@@ -264,6 +292,41 @@ function validateOptions(options) {
|
|
|
264
292
|
// or split: { '${key}': { dev: 'http://localhost:5101', prod: '/${key}' } }`
|
|
265
293
|
);
|
|
266
294
|
}
|
|
295
|
+
if (cfg.timeout !== void 0 && (typeof cfg.timeout !== "number" || !Number.isFinite(cfg.timeout) || cfg.timeout <= 0)) {
|
|
296
|
+
configError(
|
|
297
|
+
`CFG-009: remotes["${key}"].timeout must be a finite positive number (ms)`,
|
|
298
|
+
cfg.timeout,
|
|
299
|
+
"e.g. 15000\uFF08\u7701\u7565\u7528\u9ED8\u8BA4 15s\uFF09",
|
|
300
|
+
`remotes: { '${key}': { external: '\u2026', timeout: 15000 } }`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
if (cfg.retries !== void 0 && (typeof cfg.retries !== "number" || !Number.isInteger(cfg.retries) || cfg.retries < 0 || cfg.retries > 10)) {
|
|
304
|
+
configError(
|
|
305
|
+
`CFG-009: remotes["${key}"].retries must be an integer in 0..10`,
|
|
306
|
+
cfg.retries,
|
|
307
|
+
"e.g. 2\uFF08\u7701\u7565\u7528\u9ED8\u8BA4 2\uFF1B\u4E0A\u9650 10 \u9632\u9000\u907F\u98CE\u66B4\uFF09",
|
|
308
|
+
`remotes: { '${key}': { external: '\u2026', retries: 2 } }`
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
const brk = cfg.breaker;
|
|
312
|
+
if (brk) {
|
|
313
|
+
if (brk.threshold !== void 0 && (typeof brk.threshold !== "number" || !Number.isFinite(brk.threshold) || brk.threshold <= 0)) {
|
|
314
|
+
configError(
|
|
315
|
+
`CFG-009: remotes["${key}"].breaker.threshold must be a finite positive number`,
|
|
316
|
+
brk.threshold,
|
|
317
|
+
"e.g. 5\uFF08\u8FDE\u7EED\u5931\u8D25 5 \u6B21\u540E\u7194\u65AD\uFF09",
|
|
318
|
+
`remotes: { '${key}': { external: '\u2026', breaker: { threshold: 5, resetMs: 30000 } } }`
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
if (brk.resetMs !== void 0 && (typeof brk.resetMs !== "number" || !Number.isFinite(brk.resetMs) || brk.resetMs <= 0)) {
|
|
322
|
+
configError(
|
|
323
|
+
`CFG-009: remotes["${key}"].breaker.resetMs must be a finite positive number (ms)`,
|
|
324
|
+
brk.resetMs,
|
|
325
|
+
"e.g. 30000\uFF08\u7194\u65AD 30s \u540E\u534A\u5F00\uFF09",
|
|
326
|
+
`remotes: { '${key}': { external: '\u2026', breaker: { threshold: 5, resetMs: 30000 } } }`
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
267
330
|
for (const slot of ["dev", "prod", "external"]) {
|
|
268
331
|
const v = cfg[slot];
|
|
269
332
|
if (v !== void 0 && typeof v !== "string") {
|
|
@@ -282,6 +345,23 @@ function validateOptions(options) {
|
|
|
282
345
|
}
|
|
283
346
|
}
|
|
284
347
|
}
|
|
348
|
+
const corsCheck = normalizeDevCorsOrigins(options.devCorsOrigins);
|
|
349
|
+
if (!corsCheck.ok) {
|
|
350
|
+
configError(
|
|
351
|
+
`CFG-010: devCorsOrigins ${corsCheck.reason}`,
|
|
352
|
+
options.devCorsOrigins,
|
|
353
|
+
`'*'\uFF08\u5168\u653E\u5F00\uFF09\u6216\u6765\u6E90 allowlist \u6570\u7EC4`,
|
|
354
|
+
`devCorsOrigins: ['http://localhost:5100', 'http://127.0.0.1:5100']`
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
if (options.devFsRoot !== void 0 && typeof options.devFsRoot !== "boolean") {
|
|
358
|
+
configError(
|
|
359
|
+
"`devFsRoot` must be a boolean",
|
|
360
|
+
options.devFsRoot,
|
|
361
|
+
"true\uFF08dev manifest \u643A\u5E26 fsRoot\uFF0C\u73B0\u72B6\u9ED8\u8BA4\uFF09\u6216 false\uFF08\u4E0D\u66B4\u9732\u672C\u673A\u8DEF\u5F84\uFF09",
|
|
362
|
+
`devFsRoot: false`
|
|
363
|
+
);
|
|
364
|
+
}
|
|
285
365
|
}
|
|
286
366
|
function normalizeOptions(options, root, command) {
|
|
287
367
|
const warnings = [];
|
|
@@ -353,7 +433,9 @@ function normalizeOptions(options, root, command) {
|
|
|
353
433
|
pkgDependencies,
|
|
354
434
|
warnings,
|
|
355
435
|
// dev 改写开关:默认纯 remote 参与 shared 协商,宿主(有 remotes)不参与;可显式覆盖
|
|
356
|
-
devSharedSelf: options.devSharedSelf ?? remotes.length === 0
|
|
436
|
+
devSharedSelf: options.devSharedSelf ?? remotes.length === 0,
|
|
437
|
+
devCorsOrigins: options.devCorsOrigins,
|
|
438
|
+
devFsRoot: options.devFsRoot ?? true
|
|
357
439
|
};
|
|
358
440
|
}
|
|
359
441
|
|
|
@@ -362,6 +444,145 @@ import { init as initLexer, parse } from "es-module-lexer";
|
|
|
362
444
|
import MagicString from "magic-string";
|
|
363
445
|
import path2 from "path";
|
|
364
446
|
|
|
447
|
+
// src/manifest.ts
|
|
448
|
+
var MANIFEST_SCHEMA_VERSION = 1;
|
|
449
|
+
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
450
|
+
function validAssetRef(v) {
|
|
451
|
+
if (typeof v !== "string" || v.length === 0) return false;
|
|
452
|
+
if (/[\s\u0000-\u001f]/.test(v)) return false;
|
|
453
|
+
if (/^https?:\/\/[^/@\s]+:[^/@\s]+@/.test(v)) return false;
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
function validExposeName(v) {
|
|
457
|
+
return typeof v === "string" && /^\.[\w./-]+$/.test(v);
|
|
458
|
+
}
|
|
459
|
+
function parseManifest(input) {
|
|
460
|
+
const issues = [];
|
|
461
|
+
if (!isPlainObject(input)) {
|
|
462
|
+
return { issues: [{ field: "$", message: "manifest \u5FC5\u987B\u662F JSON \u5BF9\u8C61", got: typeof input }] };
|
|
463
|
+
}
|
|
464
|
+
const m = input;
|
|
465
|
+
let schemaVersion = MANIFEST_SCHEMA_VERSION;
|
|
466
|
+
if (m.schemaVersion !== void 0) {
|
|
467
|
+
if (typeof m.schemaVersion !== "number" || !Number.isInteger(m.schemaVersion)) {
|
|
468
|
+
issues.push({ field: "schemaVersion", message: "\u5FC5\u987B\u662F\u6574\u6570", got: m.schemaVersion });
|
|
469
|
+
} else if (m.schemaVersion !== MANIFEST_SCHEMA_VERSION) {
|
|
470
|
+
return {
|
|
471
|
+
issues: [
|
|
472
|
+
{
|
|
473
|
+
field: "schemaVersion",
|
|
474
|
+
message: `\u4E0D\u652F\u6301\u7684 manifest \u4E3B\u7248\u672C\uFF08\u5F53\u524D\u6D88\u8D39\u7AEF\u652F\u6301 ${MANIFEST_SCHEMA_VERSION}\uFF09`,
|
|
475
|
+
got: m.schemaVersion
|
|
476
|
+
}
|
|
477
|
+
],
|
|
478
|
+
unsupportedVersion: m.schemaVersion
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (typeof m.name !== "string" || m.name.length === 0) {
|
|
483
|
+
issues.push({ field: "name", message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32", got: m.name });
|
|
484
|
+
}
|
|
485
|
+
const exposes = m.exposes;
|
|
486
|
+
const shared = m.shared;
|
|
487
|
+
const sharedIssues = validateShared(shared);
|
|
488
|
+
issues.push(...sharedIssues);
|
|
489
|
+
if (Array.isArray(exposes)) {
|
|
490
|
+
if (m.devServer !== true) {
|
|
491
|
+
issues.push({ field: "devServer", message: "dev \u6570\u7EC4\u5F62\u6001 exposes \u5FC5\u987B\u4F34\u968F devServer: true", got: m.devServer });
|
|
492
|
+
}
|
|
493
|
+
if (typeof m.base !== "string" || !/^\/(?:.*\/)?$/.test(m.base)) {
|
|
494
|
+
issues.push({ field: "base", message: "\u5FC5\u987B\u662F\u4EE5 / \u5F00\u5934\u4E14 / \u7ED3\u5C3E\u7684\u8DEF\u5F84", got: m.base });
|
|
495
|
+
}
|
|
496
|
+
if (!validAssetRef(m.entry)) {
|
|
497
|
+
issues.push({ field: "entry", message: "\u5FC5\u987B\u662F\u5408\u6CD5\u8D44\u6E90\u5730\u5740", got: m.entry });
|
|
498
|
+
}
|
|
499
|
+
for (const [i, e] of exposes.entries()) {
|
|
500
|
+
if (!isPlainObject(e)) {
|
|
501
|
+
issues.push({ field: `exposes[${i}]`, message: "\u5FC5\u987B\u662F\u5BF9\u8C61", got: typeof e });
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
if (!validExposeName(e.name)) {
|
|
505
|
+
issues.push({ field: `exposes[${i}].name`, message: '\u5FC5\u987B\u662F "./xxx" \u5F62\u6001\u7684 expose \u540D', got: e.name });
|
|
506
|
+
}
|
|
507
|
+
if (typeof e.src !== "string" || e.src.length === 0) {
|
|
508
|
+
issues.push({ field: `exposes[${i}].src`, message: "dev \u5F62\u6001\u5FC5\u987B\u63D0\u4F9B\u6E90\u7801\u76F8\u5BF9\u8DEF\u5F84", got: e.src });
|
|
509
|
+
}
|
|
510
|
+
if (!validAssetRef(e.file)) {
|
|
511
|
+
issues.push({ field: `exposes[${i}].file`, message: "\u5FC5\u987B\u662F\u53EF\u8BF7\u6C42\u7684\u6A21\u5757\u5730\u5740", got: e.file });
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
} else if (isPlainObject(exposes)) {
|
|
515
|
+
if (!validAssetRef(m.entry)) {
|
|
516
|
+
issues.push({ field: "entry", message: "\u5FC5\u987B\u662F\u5408\u6CD5\u8D44\u6E90\u5730\u5740\uFF08\u76F8\u5BF9\u57FA\u51C6 = \u6240\u5728\u76EE\u5F55\uFF09", got: m.entry });
|
|
517
|
+
}
|
|
518
|
+
for (const [key, v] of Object.entries(exposes)) {
|
|
519
|
+
if (!validExposeName(key)) {
|
|
520
|
+
issues.push({ field: `exposes["${key}"]`, message: '\u952E\u5FC5\u987B\u662F "./xxx" \u5F62\u6001\u7684 expose \u540D' });
|
|
521
|
+
}
|
|
522
|
+
if (!isPlainObject(v)) {
|
|
523
|
+
issues.push({ field: `exposes["${key}"]`, message: "\u503C\u5FC5\u987B\u662F\u5BF9\u8C61", got: typeof v });
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
526
|
+
if (!validAssetRef(v.file)) {
|
|
527
|
+
issues.push({ field: `exposes["${key}"].file`, message: "\u5FC5\u987B\u662F\u8D44\u6E90\u8DEF\u5F84\uFF08\u76F8\u5BF9 entry \u76EE\u5F55\uFF09", got: v.file });
|
|
528
|
+
}
|
|
529
|
+
if (v.css !== void 0) {
|
|
530
|
+
if (!Array.isArray(v.css)) {
|
|
531
|
+
issues.push({ field: `exposes["${key}"].css`, message: "\u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6570\u7EC4", got: typeof v.css });
|
|
532
|
+
} else {
|
|
533
|
+
v.css.forEach((css, i) => {
|
|
534
|
+
if (!validAssetRef(css)) {
|
|
535
|
+
issues.push({ field: `exposes["${key}"].css[${i}]`, message: "\u5FC5\u987B\u662F\u8D44\u6E90\u8DEF\u5F84", got: css });
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} else {
|
|
542
|
+
issues.push({ field: "exposes", message: "\u5FC5\u987B\u662F\u6570\u7EC4\uFF08dev\uFF09\u6216\u5BF9\u8C61\uFF08prod\uFF09", got: typeof exposes });
|
|
543
|
+
}
|
|
544
|
+
if (issues.length > 0) return { issues };
|
|
545
|
+
return { manifest: input, issues };
|
|
546
|
+
}
|
|
547
|
+
function validateShared(shared) {
|
|
548
|
+
if (shared === void 0) return [];
|
|
549
|
+
const issues = [];
|
|
550
|
+
if (!Array.isArray(shared)) {
|
|
551
|
+
return [{ field: "shared", message: "\u5FC5\u987B\u662F\u6570\u7EC4", got: typeof shared }];
|
|
552
|
+
}
|
|
553
|
+
for (const [i, s] of shared.entries()) {
|
|
554
|
+
if (!isPlainObject(s)) {
|
|
555
|
+
issues.push({ field: `shared[${i}]`, message: "\u5FC5\u987B\u662F\u5BF9\u8C61", got: typeof s });
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
if (typeof s.name !== "string" || s.name.length === 0) {
|
|
559
|
+
issues.push({ field: `shared[${i}].name`, message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32", got: s.name });
|
|
560
|
+
}
|
|
561
|
+
if (typeof s.version !== "string" || s.version.length === 0) {
|
|
562
|
+
issues.push({ field: `shared[${i}].version`, message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32", got: s.version });
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return issues;
|
|
566
|
+
}
|
|
567
|
+
function isDevManifest(m) {
|
|
568
|
+
return Array.isArray(m.exposes);
|
|
569
|
+
}
|
|
570
|
+
function normalizeExposes(manifest) {
|
|
571
|
+
const out = /* @__PURE__ */ new Map();
|
|
572
|
+
if (isDevManifest(manifest)) {
|
|
573
|
+
for (const e of manifest.exposes) {
|
|
574
|
+
if (!validExposeName(e.name)) continue;
|
|
575
|
+
out.set(e.name, { name: e.name, file: e.file, css: [], src: e.src });
|
|
576
|
+
}
|
|
577
|
+
} else {
|
|
578
|
+
for (const [key, v] of Object.entries(manifest.exposes)) {
|
|
579
|
+
if (!validExposeName(key)) continue;
|
|
580
|
+
out.set(key, { name: key, file: v.file, css: Array.isArray(v.css) ? v.css.filter((c) => typeof c === "string") : [] });
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
return out;
|
|
584
|
+
}
|
|
585
|
+
|
|
365
586
|
// src/virtual.ts
|
|
366
587
|
function jsonReplacer(_k, v) {
|
|
367
588
|
return v;
|
|
@@ -505,13 +726,17 @@ function manifestUrlFor(r, command) {
|
|
|
505
726
|
const entry = command === "serve" ? r.devEntry : r.prodEntry;
|
|
506
727
|
if (!entry) return null;
|
|
507
728
|
try {
|
|
508
|
-
const
|
|
729
|
+
const hasScheme = /^[a-z][a-z\d+.-]*:/i.test(entry);
|
|
730
|
+
const isProtocolRelative = entry.startsWith("//");
|
|
731
|
+
const u = new URL(entry, hasScheme ? void 0 : "http://fulgurjs.invalid");
|
|
509
732
|
if (u.pathname.includes("@fulgurjs-entry.js")) {
|
|
510
733
|
u.pathname = u.pathname.replace("@fulgurjs-entry.js", "@fulgurjs-manifest.json");
|
|
511
734
|
} else {
|
|
512
735
|
u.pathname = u.pathname.replace(/[^/]*$/, "") + "fulgurjs-manifest.json";
|
|
513
736
|
}
|
|
514
|
-
return u.href;
|
|
737
|
+
if (hasScheme) return u.href;
|
|
738
|
+
if (isProtocolRelative) return `//${u.host}${u.pathname}${u.search}${u.hash}`;
|
|
739
|
+
return `${u.pathname}${u.search}${u.hash}`;
|
|
515
740
|
} catch {
|
|
516
741
|
return null;
|
|
517
742
|
}
|
|
@@ -656,17 +881,33 @@ function genBuildRemoteEntry(options, exposeAbsPaths) {
|
|
|
656
881
|
""
|
|
657
882
|
].join("\n");
|
|
658
883
|
}
|
|
884
|
+
function genApiFacade() {
|
|
885
|
+
return [
|
|
886
|
+
"export {",
|
|
887
|
+
" initSharing, registerShare, registerRemotes, registerRemote, registerPlugins,",
|
|
888
|
+
" loadShare, loadRemote, getContainer, preloadRemote, parseSpec,",
|
|
889
|
+
" getRuntime, shareScopeMap, unwrapDefault, version,",
|
|
890
|
+
'} from "virtual:fulgurjs-runtime";',
|
|
891
|
+
'export { definePages, validatePages } from "@fulgurjs/federation/pages";',
|
|
892
|
+
'export { default as remoteSchema } from "virtual:fulgurjs-remote-schema";',
|
|
893
|
+
""
|
|
894
|
+
].join("\n");
|
|
895
|
+
}
|
|
659
896
|
function genDevManifest(options, base) {
|
|
660
897
|
const b = base.endsWith("/") ? base : `${base}/`;
|
|
661
898
|
return {
|
|
899
|
+
schemaVersion: MANIFEST_SCHEMA_VERSION,
|
|
662
900
|
id: options.name,
|
|
663
901
|
name: options.name,
|
|
664
902
|
version: options.pkgDependencies?.["fulgurjs"] ?? "0.0.0",
|
|
665
903
|
devServer: true,
|
|
666
904
|
base: b,
|
|
667
905
|
entry: `${b}@fulgurjs-entry.js`,
|
|
668
|
-
/**
|
|
669
|
-
|
|
906
|
+
/**
|
|
907
|
+
* 本地联调时供宿主端 dts 类型直连(见 dts.ts);远程不在本机时宿主回退 any 桩。
|
|
908
|
+
* WP5:devFsRoot: false 时不写入(本机路径不外发);该字段永不进入 prod manifest。
|
|
909
|
+
*/
|
|
910
|
+
...options.devFsRoot === false ? {} : { fsRoot: options.root },
|
|
670
911
|
exposes: options.exposes.map((e) => ({
|
|
671
912
|
name: e.name,
|
|
672
913
|
src: e.import,
|
|
@@ -688,6 +929,7 @@ function genDevManifest(options, base) {
|
|
|
688
929
|
}
|
|
689
930
|
function genProdManifest(options, exposeFiles, entryFile) {
|
|
690
931
|
return {
|
|
932
|
+
schemaVersion: MANIFEST_SCHEMA_VERSION,
|
|
691
933
|
id: options.name,
|
|
692
934
|
name: options.name,
|
|
693
935
|
entry: entryFile,
|
|
@@ -869,6 +1111,7 @@ async function transformModule(code, id, ctx) {
|
|
|
869
1111
|
cjsEdited = true;
|
|
870
1112
|
}
|
|
871
1113
|
if (!cjsEdited) return null;
|
|
1114
|
+
ctx.onRewrite?.();
|
|
872
1115
|
return { code, map: null };
|
|
873
1116
|
}
|
|
874
1117
|
await ensureLexer();
|
|
@@ -991,6 +1234,7 @@ export { ${nsAs[1]} };`);
|
|
|
991
1234
|
}
|
|
992
1235
|
}
|
|
993
1236
|
if (!edited) return null;
|
|
1237
|
+
ctx.onRewrite?.();
|
|
994
1238
|
if (usesRuntimeHelpers) {
|
|
995
1239
|
const runtimeSpec = JSON.stringify(ctx.devUrls?.runtime ?? "virtual:fulgurjs-runtime");
|
|
996
1240
|
s.prepend(
|
|
@@ -1016,7 +1260,22 @@ async function fetchManifest(devEntry, attempts = 30, delayMs = 2e3) {
|
|
|
1016
1260
|
for (let i = 0; i < attempts; i++) {
|
|
1017
1261
|
try {
|
|
1018
1262
|
const res = await fetch(manifestUrl, { signal: AbortSignal.timeout(3e3) });
|
|
1019
|
-
if (res.ok)
|
|
1263
|
+
if (res.ok) {
|
|
1264
|
+
const parsed = parseManifest(await res.json());
|
|
1265
|
+
if (parsed.unsupportedVersion) {
|
|
1266
|
+
console.warn(
|
|
1267
|
+
`[fulgurjs] dts: remote manifest schemaVersion=${parsed.unsupportedVersion} \u4E0D\u88AB\u5F53\u524D\u63D2\u4EF6\u652F\u6301\uFF08\u672C\u673A\u652F\u6301 1\uFF09\uFF1B\u7C7B\u578B\u6620\u5C04\u8DF3\u8FC7\u3002\u8BF7\u5BF9\u9F50\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u7248\u672C\u3002`
|
|
1268
|
+
);
|
|
1269
|
+
return null;
|
|
1270
|
+
}
|
|
1271
|
+
if (parsed.issues.length > 0) {
|
|
1272
|
+
console.warn(
|
|
1273
|
+
`[fulgurjs] dts: remote manifest \u5951\u7EA6\u6821\u9A8C\u5931\u8D25\uFF08${manifestUrl.href}\uFF09\uFF1A` + parsed.issues.map((x) => `${x.field}: ${x.message}`).join("\uFF1B") + `\u3002\u7C7B\u578B\u6620\u5C04\u8DF3\u8FC7\u3002`
|
|
1274
|
+
);
|
|
1275
|
+
return null;
|
|
1276
|
+
}
|
|
1277
|
+
return parsed.manifest;
|
|
1278
|
+
}
|
|
1020
1279
|
} catch {
|
|
1021
1280
|
}
|
|
1022
1281
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
@@ -1079,7 +1338,7 @@ function resolveDtsMode(dtsOpt) {
|
|
|
1079
1338
|
return (typeof dtsOpt === "object" ? dtsOpt.mode : void 0) ?? "source";
|
|
1080
1339
|
}
|
|
1081
1340
|
function buildShimModule(abs, moduleSpecifier) {
|
|
1082
|
-
const lines = [`declare module
|
|
1341
|
+
const lines = [`declare module ${JSON.stringify(moduleSpecifier)} {`];
|
|
1083
1342
|
if (abs.endsWith(".vue")) {
|
|
1084
1343
|
lines.push(` import type { DefineComponent } from 'vue'`);
|
|
1085
1344
|
lines.push(` const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, any>`);
|
|
@@ -1116,9 +1375,18 @@ async function generateDevTypes(options, _server) {
|
|
|
1116
1375
|
continue;
|
|
1117
1376
|
}
|
|
1118
1377
|
const remoteRoot = manifest.fsRoot;
|
|
1119
|
-
if (!remoteRoot
|
|
1378
|
+
if (!remoteRoot) {
|
|
1120
1379
|
console.warn(
|
|
1121
|
-
`[fulgurjs] dts: remote "${remote.key}"
|
|
1380
|
+
`[fulgurjs] dts: remote "${remote.key}" \u7684 manifest \u672A\u643A\u5E26 fsRoot\uFF08devFsRoot: false \u6216\u8FDC\u7A0B\u63D2\u4EF6\u7248\u672C\u8FC7\u65E7\uFF09\uFF1B\u7C7B\u578B\u6620\u5C04\u964D\u7EA7\u4E3A any \u6869\u3002\u540C\u673A\u8054\u8C03\u9700\u8FDC\u7A0B devFsRoot: true\uFF08\u9ED8\u8BA4\uFF09\u5E76\u91CD\u542F\u5176 dev server\u3002`
|
|
1381
|
+
);
|
|
1382
|
+
continue;
|
|
1383
|
+
}
|
|
1384
|
+
let realRoot;
|
|
1385
|
+
try {
|
|
1386
|
+
realRoot = fs2.realpathSync(remoteRoot);
|
|
1387
|
+
} catch {
|
|
1388
|
+
console.warn(
|
|
1389
|
+
`[fulgurjs] dts: remote "${remote.key}" is not on this machine (fsRoot unreachable); type mapping skipped (module types fall back to any).`
|
|
1122
1390
|
);
|
|
1123
1391
|
continue;
|
|
1124
1392
|
}
|
|
@@ -1126,45 +1394,78 @@ async function generateDevTypes(options, _server) {
|
|
|
1126
1394
|
`// \u81EA\u52A8\u751F\u6210\uFF1Afulgurjs-federation dev \u7C7B\u578B\u76F4\u8FDE\uFF08remote: ${remote.name}\uFF0Cmode: ${mode}\uFF09`,
|
|
1127
1395
|
`// \u91CD\u65B0\u751F\u6210\uFF1A\u91CD\u542F host dev server`
|
|
1128
1396
|
];
|
|
1397
|
+
let accepted = 0;
|
|
1129
1398
|
for (const expose of manifest.exposes ?? []) {
|
|
1130
|
-
const
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1399
|
+
const skipped = (reason) => console.warn(`[fulgurjs] dts: remote "${remote.key}" expose ${JSON.stringify(expose.name)} \u8DF3\u8FC7\uFF1A${reason}`);
|
|
1400
|
+
const src = expose.src;
|
|
1401
|
+
if (!src || typeof src !== "string") {
|
|
1402
|
+
skipped("src \u7F3A\u5931");
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
if (src.startsWith("/") || /^[a-z]+:/i.test(src)) {
|
|
1406
|
+
skipped(`src \u5FC5\u987B\u662F\u76F8\u5BF9\u8DEF\u5F84\uFF0Cgot ${JSON.stringify(src)}`);
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
if (src.split("/").includes("..")) {
|
|
1410
|
+
skipped(`src \u4E0D\u5F97\u5305\u542B ..\uFF0Cgot ${JSON.stringify(src)}`);
|
|
1411
|
+
continue;
|
|
1412
|
+
}
|
|
1413
|
+
const abs = path3.join(realRoot, src);
|
|
1414
|
+
let realAbs;
|
|
1415
|
+
try {
|
|
1416
|
+
realAbs = fs2.realpathSync(abs);
|
|
1417
|
+
} catch {
|
|
1418
|
+
skipped(`\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728\uFF08${src}\uFF09`);
|
|
1419
|
+
continue;
|
|
1420
|
+
}
|
|
1421
|
+
if (path3.relative(realRoot, realAbs).startsWith("..")) {
|
|
1422
|
+
skipped(`\u89E3\u6790\u7ED3\u679C\u8D8A\u51FA fsRoot\uFF08${src} \u2192 ${realAbs}\uFF09`);
|
|
1423
|
+
continue;
|
|
1424
|
+
}
|
|
1425
|
+
if (!fs2.existsSync(realAbs)) continue;
|
|
1426
|
+
const rel = path3.relative(outDir, realAbs).split(path3.sep).join("/");
|
|
1427
|
+
const importPath = realAbs.endsWith(".vue") ? sourceImportPath(rel) : stripTsExtension(sourceImportPath(rel));
|
|
1134
1428
|
const moduleSpecifier = `${remote.key}/${expose.name.replace(/^\.\//, "")}`;
|
|
1429
|
+
const moduleLiteral = JSON.stringify(moduleSpecifier);
|
|
1430
|
+
const importLiteral = JSON.stringify(importPath);
|
|
1135
1431
|
lines.push("");
|
|
1136
1432
|
if (mode === "shim") {
|
|
1137
|
-
lines.push(buildShimModule(
|
|
1433
|
+
lines.push(buildShimModule(realAbs, moduleSpecifier));
|
|
1434
|
+
accepted++;
|
|
1138
1435
|
continue;
|
|
1139
1436
|
}
|
|
1140
|
-
if (
|
|
1141
|
-
lines.push(`declare module
|
|
1437
|
+
if (realAbs.endsWith(".vue")) {
|
|
1438
|
+
lines.push(`declare module ${moduleLiteral} {`);
|
|
1142
1439
|
lines.push(` import type { DefineComponent } from 'vue'`);
|
|
1143
1440
|
lines.push(` const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>`);
|
|
1144
1441
|
lines.push(` export default component`);
|
|
1145
|
-
lines.push(` export * from
|
|
1442
|
+
lines.push(` export * from ${importLiteral}`);
|
|
1146
1443
|
lines.push(`}`);
|
|
1147
1444
|
} else {
|
|
1148
|
-
lines.push(`declare module
|
|
1149
|
-
const names = extractTsExportNames(fs2.readFileSync(
|
|
1445
|
+
lines.push(`declare module ${moduleLiteral} {`);
|
|
1446
|
+
const names = extractTsExportNames(fs2.readFileSync(realAbs, "utf8"));
|
|
1150
1447
|
if (names.length > 0) {
|
|
1151
|
-
lines.push(` export { ${names.join(", ")} } from
|
|
1448
|
+
lines.push(` export { ${names.join(", ")} } from ${importLiteral}`);
|
|
1152
1449
|
} else {
|
|
1153
|
-
lines.push(` export * from
|
|
1450
|
+
lines.push(` export * from ${importLiteral}`);
|
|
1154
1451
|
}
|
|
1155
|
-
if (sourceHasDefaultExport(
|
|
1452
|
+
if (sourceHasDefaultExport(realAbs)) lines.push(` export { default } from ${importLiteral}`);
|
|
1156
1453
|
lines.push(`}`);
|
|
1157
1454
|
}
|
|
1455
|
+
accepted++;
|
|
1158
1456
|
}
|
|
1159
|
-
|
|
1457
|
+
if (accepted > 0) {
|
|
1458
|
+
fs2.writeFileSync(path3.join(outDir, `${remote.key}.d.ts`), `${lines.join("\n")}
|
|
1160
1459
|
`);
|
|
1460
|
+
}
|
|
1161
1461
|
console.log(
|
|
1162
|
-
`[fulgurjs] dts: generated ${dir}/${remote.key}.d.ts (${manifest.exposes?.length ?? 0} exposes, mode=${mode}). \u786E\u4FDD tsconfig include \u5305\u542B "${dir}" \u4EE5\u83B7\u5F97\u7C7B\u578B\u8865\u5168\u3002`
|
|
1462
|
+
`[fulgurjs] dts: generated ${dir}/${remote.key}.d.ts (${accepted}/${manifest.exposes?.length ?? 0} exposes, mode=${mode}). \u786E\u4FDD tsconfig include \u5305\u542B "${dir}" \u4EE5\u83B7\u5F97\u7C7B\u578B\u8865\u5168\u3002`
|
|
1163
1463
|
);
|
|
1164
1464
|
}
|
|
1165
1465
|
}
|
|
1166
1466
|
|
|
1167
1467
|
// src/diagnostics.ts
|
|
1468
|
+
import path4 from "path";
|
|
1168
1469
|
function formatFulgurjsDiagnostic(input) {
|
|
1169
1470
|
const ctx = input.details ? `
|
|
1170
1471
|
\u4E0A\u4E0B\u6587\uFF1A${JSON.stringify(input.details)}` : "";
|
|
@@ -1187,6 +1488,33 @@ async function isPortReachable(host, port, timeoutMs = 800) {
|
|
|
1187
1488
|
socket.connect(port, host);
|
|
1188
1489
|
});
|
|
1189
1490
|
}
|
|
1491
|
+
var __debugEnvCache = "";
|
|
1492
|
+
var __debugEnabledCache = {};
|
|
1493
|
+
function debugEnabled(category) {
|
|
1494
|
+
const spec = process.env.FULGURJS_DEBUG ?? process.env.DEBUG ?? "";
|
|
1495
|
+
if (spec !== __debugEnvCache) {
|
|
1496
|
+
__debugEnvCache = spec;
|
|
1497
|
+
__debugEnabledCache = {};
|
|
1498
|
+
}
|
|
1499
|
+
if (category in __debugEnabledCache) return __debugEnabledCache[category];
|
|
1500
|
+
const patterns = spec.split(",").map((x) => x.trim()).filter(Boolean);
|
|
1501
|
+
const enabled = patterns.some((p) => p === "fulgurjs" || p === "fulgurjs:*" || p === `fulgurjs:${category}`);
|
|
1502
|
+
__debugEnabledCache[category] = enabled;
|
|
1503
|
+
return enabled;
|
|
1504
|
+
}
|
|
1505
|
+
function debugLog(category, data) {
|
|
1506
|
+
if (!debugEnabled(category)) return;
|
|
1507
|
+
console.error(`[fulgurjs:debug:${category}] ${JSON.stringify(data)}`);
|
|
1508
|
+
}
|
|
1509
|
+
function redactModulePath(id, root) {
|
|
1510
|
+
const clean = id.split("?")[0];
|
|
1511
|
+
try {
|
|
1512
|
+
const rel = path4.relative(root, clean);
|
|
1513
|
+
if (rel && !rel.startsWith("..") && !path4.isAbsolute(rel)) return rel;
|
|
1514
|
+
} catch {
|
|
1515
|
+
}
|
|
1516
|
+
return clean.split("/").pop() ?? clean;
|
|
1517
|
+
}
|
|
1190
1518
|
|
|
1191
1519
|
// src/remote-schema.ts
|
|
1192
1520
|
function manifestUrlOf(devEntry) {
|
|
@@ -1213,8 +1541,35 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1213
1541
|
try {
|
|
1214
1542
|
const res = await fetch(u, { signal: AbortSignal.timeout(3e3) });
|
|
1215
1543
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1544
|
+
const parsed = parseManifest(await res.json());
|
|
1545
|
+
if (parsed.unsupportedVersion) {
|
|
1546
|
+
schema[remote.key] = { exposes: [], exists: false };
|
|
1547
|
+
console.warn(
|
|
1548
|
+
formatFulgurjsDiagnostic({
|
|
1549
|
+
code: "DEV-002",
|
|
1550
|
+
symptom: `remote "${remote.key}" \u7684 manifest schemaVersion=${parsed.unsupportedVersion} \u4E0D\u53D7\u652F\u6301\uFF08\u672C\u673A\u652F\u6301 1\uFF09`,
|
|
1551
|
+
cause: "\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u5927\u7248\u672C\u4E0D\u4E00\u81F4",
|
|
1552
|
+
fix: "\u5BF9\u9F50\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u7248\u672C\u540E\u91CD\u542F dev server",
|
|
1553
|
+
details: { remote: remote.key, url: u.href }
|
|
1554
|
+
})
|
|
1555
|
+
);
|
|
1556
|
+
continue;
|
|
1557
|
+
}
|
|
1558
|
+
if (parsed.issues.length > 0 || !parsed.manifest) {
|
|
1559
|
+
schema[remote.key] = { exposes: [], exists: false };
|
|
1560
|
+
console.warn(
|
|
1561
|
+
formatFulgurjsDiagnostic({
|
|
1562
|
+
code: "DEV-002",
|
|
1563
|
+
symptom: `remote "${remote.key}" \u7684 dev manifest \u5951\u7EA6\u6821\u9A8C\u5931\u8D25\uFF08${u.href}\uFF09`,
|
|
1564
|
+
cause: parsed.issues.map((x) => `${x.field}: ${x.message}`).join("\uFF1B"),
|
|
1565
|
+
fix: "\u6838\u5BF9 remote \u7684 federation \u914D\u7F6E exposes\uFF0C\u5E76\u786E\u8BA4 @fulgurjs/federation \u7248\u672C\u4E0E\u5BBF\u4E3B\u4E00\u81F4",
|
|
1566
|
+
details: { remote: remote.key, url: u.href, issues: parsed.issues.slice(0, 5) }
|
|
1567
|
+
})
|
|
1568
|
+
);
|
|
1569
|
+
continue;
|
|
1570
|
+
}
|
|
1571
|
+
const manifest = parsed.manifest;
|
|
1572
|
+
const exposes = [...normalizeExposes(manifest).keys()];
|
|
1218
1573
|
schema[remote.key] = { exposes, exists: true };
|
|
1219
1574
|
if (exposes.length === 0) {
|
|
1220
1575
|
console.warn(
|
|
@@ -1223,11 +1578,11 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1223
1578
|
symptom: `remote "${remote.key}" \u7684 dev manifest \u53EF\u8FBE\u4F46 exposes \u4E3A\u7A7A\uFF08${u.href}\uFF09`,
|
|
1224
1579
|
cause: "remote \u4FA7 federation({ exposes }) \u4E3A\u7A7A\uFF0C\u6216\u5176\u63D2\u4EF6\u7248\u672C\u8FC7\u65E7\u5BFC\u81F4 manifest \u7F3A\u5B57\u6BB5",
|
|
1225
1580
|
fix: "\u6838\u5BF9 remote \u7684 federation \u914D\u7F6E exposes\uFF0C\u5E76\u786E\u8BA4 @fulgurjs/federation \u7248\u672C\u4E0E\u5BBF\u4E3B\u4E00\u81F4",
|
|
1226
|
-
details: { remote: remote.key, url: u.href, pluginVersion: manifest
|
|
1581
|
+
details: { remote: remote.key, url: u.href, pluginVersion: manifest.version }
|
|
1227
1582
|
})
|
|
1228
1583
|
);
|
|
1229
1584
|
}
|
|
1230
|
-
const remoteVersion = manifest
|
|
1585
|
+
const remoteVersion = manifest.version;
|
|
1231
1586
|
if (remoteVersion && remoteVersion !== options.pluginVersion) {
|
|
1232
1587
|
console.warn(
|
|
1233
1588
|
formatFulgurjsDiagnostic({
|
|
@@ -1263,17 +1618,17 @@ function genEmptyRemoteSchemaModule() {
|
|
|
1263
1618
|
|
|
1264
1619
|
// src/vite-cache.ts
|
|
1265
1620
|
import fs3 from "fs";
|
|
1266
|
-
import
|
|
1621
|
+
import path5 from "path";
|
|
1267
1622
|
function syncViteCacheMarker(root, pluginVersion, log) {
|
|
1268
|
-
const viteDir =
|
|
1269
|
-
const marker =
|
|
1623
|
+
const viteDir = path5.join(root, "node_modules", ".vite");
|
|
1624
|
+
const marker = path5.join(viteDir, "fulgurjs-version.txt");
|
|
1270
1625
|
try {
|
|
1271
1626
|
if (fs3.existsSync(viteDir)) {
|
|
1272
1627
|
const prev = fs3.existsSync(marker) ? fs3.readFileSync(marker, "utf8").trim() : "";
|
|
1273
1628
|
if (prev === pluginVersion) return;
|
|
1274
1629
|
fs3.rmSync(viteDir, { recursive: true, force: true });
|
|
1275
1630
|
log(
|
|
1276
|
-
`[fulgurjs] \u63D2\u4EF6\u7248\u672C\u53D8\u5316\uFF08${prev || "\u65E0\u8BB0\u5F55"} \u2192 ${pluginVersion}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664 ${
|
|
1631
|
+
`[fulgurjs] \u63D2\u4EF6\u7248\u672C\u53D8\u5316\uFF08${prev || "\u65E0\u8BB0\u5F55"} \u2192 ${pluginVersion}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664 ${path5.relative(root, viteDir)} \u9884\u6784\u5EFA\u7F13\u5B58\uFF08\u907F\u514D\u65E7\u95E8\u9762\u7B7E\u540D 404 / DEV-009\uFF09\u3002\u672C\u6B21\u542F\u52A8\u5C06\u91CD\u65B0\u9884\u6784\u5EFA\uFF0C\u9996\u8F6E 30~60s \u5C5E\u6682\u6001\uFF08DEV-010\uFF09\u3002`
|
|
1277
1632
|
);
|
|
1278
1633
|
}
|
|
1279
1634
|
fs3.mkdirSync(viteDir, { recursive: true });
|
|
@@ -1286,7 +1641,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
|
|
|
1286
1641
|
}
|
|
1287
1642
|
|
|
1288
1643
|
// src/runtime-code.gen.ts
|
|
1289
|
-
var runtime_code_gen_default = 'var X=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),E=/^\\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.2";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}k(u,e);let $=l.get(u);if($&&$!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${$}", cannot re-init with "${a}"`);return typeof u.init=="function"&&await u.init(t),l.set(u,a),e.container=u,e.state="loaded",e.debug.status="loaded",c.fails=0,u})();e.containerPromise=R;try{return await R}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),c.fails+=1,c.fails>=ae&&(c.openUntil=Date.now()+se,c.fails=0),s instanceof g)throw w({remote:e.name,error:s}),s;if(s?.code)throw w({remote:e.name,error:s}),s;let u=new g(S.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw w({remote:e.name,error:u}),u}}function N(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:G(e.slice(i+1))}}function G(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:c}=N(e);m.beforeLoadRemote?.({remote:a,module:c});let R=n.get(a);if(!R)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await x(R,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(!c)return s;let u=`${a}@${R.shareScope||"default"}#${c}`;r.has(u)||r.set(u,s.get(c).catch(f=>{throw r.delete(u),f instanceof g||f?.code?f:new g(S.REMOTE_LOAD_FAILED,`failed to load module "${c}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:c})}));let d;try{d=await r.get(u)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(m.afterLoadRemote?.({remote:a,module:c,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(S.EMPTY_EXPORTS,`no exports: ${c} @ ${a}`,{remote:a,module:c});w({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function W(e){let i=n.get(e);if(!i)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return x(i)}async function B(e,i={}){let{remote:a}=N(e),c=n.get(a);if(!c)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let R=i.mode??"preload",s=(u,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${u}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=u,R==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(c.manifestUrl){let u=await fetch(c.manifestUrl,{cache:"no-cache"});if(u.ok){let d=await u.json();s(c.entry,"modulepreload");let f=d.exposes??{};for(let _ of Object.keys(f)){let $=f[_];$?.file&&s(new URL($.file,c.entry).href,"modulepreload");for(let p of $?.css??[])s(new URL(p,c.entry).href,"style")}return}}s(c.entry,"modulepreload")}catch(u){w({remote:a,error:new g(S.PRELOAD_FAILED,String(u?.message??u),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:F,registerShare:V,registerRemotes:I,registerRemote:D,registerPlugins:H,loadShare:K,loadRemote:J,getContainer:W,preloadRemote:B,parseSpec:N}}var C=globalThis,b=C.__FULGURJS_RUNTIME__??ce();C.__FULGURJS_RUNTIME__=b;try{Object.freeze(b)}catch{}var he=U;function ye(){return b}var Ee=b.initSharing,Re=b.registerShare,Se=b.registerRemotes,we=b.registerRemote,be=b.registerPlugins,_e=b.loadShare,$e=b.loadRemote,Me=b.getContainer,ve=b.preloadRemote,je=b.shareScopeMap;function Te(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var Oe=b;export{Oe as default,Me as getContainer,ye as getRuntime,Ee as initSharing,$e as loadRemote,_e as loadShare,ve as preloadRemote,be as registerPlugins,we as registerRemote,Se as registerRemotes,Re as registerShare,b as runtime,je as shareScopeMap,Te as unwrapDefault,he as version};\n';
|
|
1644
|
+
var runtime_code_gen_default = 'var oe=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function I(o){let i=oe.exec(String(o).trim());return i?{major:Number(i[1]),minor:Number(i[2]??0),patch:Number(i[3]??0),pre:i[4]?i[4].split("."):[]}:null}function ie(o,i){if(o.length===0&&i.length===0)return 0;if(o.length===0)return 1;if(i.length===0)return-1;let s=Math.max(o.length,i.length);for(let n=0;n<s;n++){let f=o[n],y=i[n];if(f===void 0)return-1;if(y===void 0)return 1;let R=/^\\d+$/.test(f),w=/^\\d+$/.test(y);if(R&&w){let T=Number(f)-Number(y);if(T!==0)return T}else{if(R!==w)return R?-1:1;if(f!==y)return f<y?-1:1}}return 0}function j(o,i){let s=I(o),n=I(i);return!s||!n?o<i?-1:o>i?1:0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:ie(s.pre,n.pre)}var se=/^[a-z]+[+:-]/i;function P(o,i){if(i===!1||i==null||i==="")return!0;let s=String(i).trim();return!s||s==="*"||s==="latest"||se.test(s)?!0:s.split("||").some(n=>ae(o,n.trim()))}function ae(o,i){if(!i||i==="*")return!I(o)?.pre.length;let s=i.split(/\\s+-\\s+/);if(s.length===2){let y=s[0].trim(),R=s[1].trim();return!(!P(o,`>=${y}`)||!P(o,`<=${R}`))}let n=I(o);if(!n)return!1;let f=ce(i);if(f===null)return!0;for(let y of f)if(!pe(n,o,y))return!1;return!(n.pre.length>0&&!f.some(y=>y.ver.pre.length>0)&&!f.some(R=>R.ver.major===n.major&&R.ver.minor===n.minor&&R.ver.patch===n.patch))}function ce(o){let i=[],s=o.trim().split(/\\s+/).filter(Boolean);if(s.length===0)return null;for(let n of s){let f=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(n);if(!f)return null;let y=f[1],R=f[2],w=le(y,R);if(w===null)return null;i.push(...w)}return i}function le(o,i){let s=me(i);if(!s)return null;let{ver:n,partial:f}=s;switch(o){case"^":{let y=ue(n);return y?[{op:">=",ver:n},{op:"<",ver:y}]:null}case"~":{let y=f>=2?{major:n.major,minor:n.minor+1,patch:0,pre:[]}:{major:n.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:n},{op:"<",ver:y}]}case">=":return[{op:">=",ver:n}];case">":return f===1?[{op:">=",ver:{major:n.major+1,minor:0,patch:0,pre:[]}}]:f===2?[{op:">=",ver:{major:n.major,minor:n.minor+1,patch:0,pre:[]}}]:[{op:">",ver:n}];case"<":return f===1?[{op:"<",ver:{major:n.major,minor:0,patch:0,pre:[]}}]:f===2?[{op:"<",ver:{major:n.major,minor:n.minor,patch:0,pre:[]}}]:[{op:"<",ver:n}];case"<=":return[{op:"<=",ver:n}];case"=":case void 0:return f===1?[{op:">=",ver:n},{op:"<",ver:{major:n.major+1,minor:0,patch:0,pre:[]}}]:f===2?[{op:">=",ver:n},{op:"<",ver:{major:n.major,minor:n.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:n}];default:return null}}function ue(o){return o.major>0?{major:o.major+1,minor:0,patch:0,pre:[]}:o.minor>0?{major:0,minor:o.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:o.patch+1,pre:[]}}function me(o){let i=o.replace(/^v/,"").trim();if(!i||i==="*"||i==="x"||i==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let s=i.split("."),n=[],f=0;for(let w of s.slice(0,3))if(/^\\d+$/.test(w))n.push(Number(w)),f++;else{if(w==="x"||w==="X"||w==="*")break;break}let y=i.split("-"),R=y.length>1?y.slice(1).join("-").split("+")[0].split("."):[];return f===0&&R.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:n[0]??0,minor:n[1]??0,patch:n[2]??0,pre:R},partial:f}}function fe(o,i){switch(i){case">=":return o>=0;case">":return o>0;case"<":return o<0;case"<=":return o<=0;case"=":return o===0}}function pe(o,i,s){let n=`${o.major}.${o.minor}.${o.patch}`+(o.pre.length?`-${o.pre.join(".")}`:"");if(s.upper)return!(!(j(n,`${s.ver.major}.${s.ver.minor}.${s.ver.patch}`+(s.ver.pre.length?`-${s.ver.pre.join(".")}`:""))>=0)||!(j(n,`${s.upper.major}.${s.upper.minor}.${s.upper.patch}`)<0));let f=j(n,`${s.ver.major}.${s.ver.minor}.${s.ver.patch}`+(s.ver.pre.length?`-${s.ver.pre.join(".")}`:"")),y=fe(f,s.op);return s.ver.pre.length>0&&o.pre.length===0&&(s.op===">"||s.op==="<")?!1:y}var b=class extends Error{code;details;constructor(i,s,n){super(`[fulgurjs:${i}] ${s}`),this.name="FgError",this.code=i,this.details=n}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var q="2.1.0";var x=15e3,z=2,de=5,ge=3e4,he=4e3,ye=.2;function Ee(){let o=Object.create(null),i=new Map,s=[],n=new Map,f=new Map,y=new WeakMap,R=new WeakMap,w={},T=()=>{for(let e of s)try{e.init?.(w)}catch(t){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,t)}},N=e=>o[e]??=Object.create(null);function $(e){try{w.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function B(e="default"){return N(e),o}function J(e,t,r,l,h={}){let a=N(e||"default"),p=Object.hasOwn(a,t)?a[t]:void 0,d=p&&typeof p=="object"?p:void 0;d||(d=Object.create(null),a[t]=d),!(Object.hasOwn(d,r)&&d[r])&&(d[r]={version:r,get:l,from:h.from??"unknown",eager:!!h.eager,loaded:!!h.loaded})}function G(e){let t=(r,l,h)=>{if(r===void 0)return;if(!(typeof r=="number"&&(h?Number.isInteger(r)&&r>=0&&r<=10:Number.isFinite(r)&&r>0)))throw new Error(`[fulgurjs] registerRemote("${e.name}"): ${l} must be a ${h?"integer 0..10":"finite positive number"}, got ${String(r)}`)};t(e.timeout,"timeout"),t(e.retries,"retries",!0),e.breaker&&(t(e.breaker.threshold,"breaker.threshold"),t(e.breaker.resetMs,"breaker.resetMs"))}function F(e){for(let t of e){G(t);let r=i.get(t.name);i.set(t.name,{timeout:x,retries:z,...r,...t,breakerThreshold:t.breaker?.threshold??r?.breakerThreshold??de,breakerResetMs:t.breaker?.resetMs??r?.breakerResetMs??ge,state:r?.state??"idle",breakerState:r?.breakerState??{fails:0,openUntil:0},entryInflight:r?.entryInflight??new Map,debug:r?.debug??{entry:t.entry,status:"idle"}})}}function X(e){F([e])}function Y(e){s.push(...e),T()}async function Z(e,t={}){let r=t.shareScope||"default",l=t.shareKey||e,a=N(r)[l]||{},p=Object.keys(a),d=t.requiredVersion,g=p.filter(c=>d===void 0||d===!1||P(c,d)),m;if(t.singleton&&p.length>0){let c=p.filter(u=>a[u].loaded);if(m=[...c.length?c:p].sort(j).pop(),p.length>1||!g.includes(m)){let u=a[m],k=`singleton skew "${l}": req "${d??"any"}" use ${m} from ${u.from}`;if(t.strictVersion){let v=new b(S.SHARE_STRICT_VERSION,k,{shareKey:l,requiredVersion:d});throw $({remote:u.from,error:v}),v}console.warn(`[fulgurjs:MFU-010] ${k}`)}}else if(m=[...g].sort(j).pop(),!m){if(t.strictVersion){let u=new b(S.SHARE_STRICT_VERSION,`no satisfying version for "${l}" (required "${d}") in share scope "${r}"`);throw $({remote:l,error:u}),u}if(t.fallback)return t.fallback();let c=new b(S.SHARE_NOT_AVAILABLE,`shared "${l}" (${d??"any"}) unavailable in scope "${r}" (no local fallback)`,{shareKey:l,requiredVersion:d});throw $({remote:l,error:c}),c}let E=a[m];if(w.resolveShare){let c=await w.resolveShare({shareKey:l,shareScope:r,requiredVersion:d,picked:E,available:Object.values(a)});c&&(E=c)}return E.loaded=!0,E.get()}function Q(e){try{let t=new URL(e,typeof location<"u"?location.href:"http://f.invalid");return t.protocol+"//"+t.host+t.pathname}catch{return String(e).replace(/[?#].*$/,"")}}function C(e,t,r){return new Promise((l,h)=>{let a=setTimeout(()=>h(new Error(`timeout after ${t}ms: ${r}`)),t);e.then(p=>{clearTimeout(a),l(p)},p=>{clearTimeout(a),h(p)})})}let ee=e=>new Promise(t=>setTimeout(t,e));function A(e,t){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${t.name}" does not export a container interface (get/init)`);if(e.name&&t.name&&e.name!==t.name){let r=`remoteEntry self-reported name "${e.name}" mismatches configured name "${t.name}"`;if(t.promise)console.warn(`[fulgurjs] ${r} (promise-based remote, continuing)`);else throw Object.assign(new Error(r),{code:S.REMOTE_NAME_MISMATCH})}}async function D(e,t){let r=t.entryInflight.get(e),l=r??import(e);return r||(t.entryInflight.set(e,l),l.catch(()=>t.entryInflight.delete(e))),C(l,t.timeout??x,`load remoteEntry ${e}`)}async function V(e,t){let r=e.shareScope||"default";if(e.container){let a=R.get(e.container);if(a&&a!==r)throw new b(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${a}", cannot re-init with "${r}"`);return e.container}if(e.containerPromise)return e.containerPromise;let l=e.breakerState;if(l.openUntil>Date.now()){let a=new b(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(l.openUntil).toISOString()}`,{remote:e.name});throw $({remote:e.name,error:a}),a}e.state="loading",e.debug.status="loading";let h=(async()=>{let a=[];if(e.promise)a.push(async()=>{let c=await C(e.promise(),e.timeout??x,`resolve promise remote "${e.name}"`),u=typeof c=="string"?await D(c,e):c;return A(u,e),u});else for(let c of[e.entry,...e.fallback??[]])a.push(async()=>{let u=await D(c,e);return A(u,e),u});let p,d,g=!1,m=t?.retries??e.retries??z;for(let c of a){for(let u=0;u<=m;u++){let k=performance.now();try{p=await c(),e.lastLoadMs=Math.round(performance.now()-k),e.debug.lastLoadMs=e.lastLoadMs,g=!0;break}catch(v){if(d=v,v?.code)throw v;u<m&&await ee(Math.min(he,200*2**u)*(1-ye*(1-2*Math.random())))}}if(g)break}if(!g||!p){let c=Q(e.entry),u=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(u.push(`1. is the remote dev server running? open ${c} in a browser \\u2014 it must return JS, not HTML`),u.push("2. is the URL correct in federation({ remotes })? dev/prod entries can differ"),u.push("3. CORS: the remote dev server must allow cross-origin requests (check its server.cors)")):(u.push(`1. is the remote deployed? open ${c} in a browser \\u2014 it must return JS`),u.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS (check try_files)")),new b(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${c}: ${String(d?.message??d)}\n`+u.join(`\n`),{remote:e.name})}A(p,e);let E=R.get(p);if(E&&E!==r)throw new b(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${E}", cannot re-init with "${r}"`);return typeof p.init=="function"&&await p.init(o),R.set(p,r),e.container=p,e.state="loaded",e.debug.status="loaded",l.fails=0,p})();e.containerPromise=h;try{return await h}catch(a){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(a?.message??a),l.fails+=1,l.fails>=e.breakerThreshold&&(l.openUntil=Date.now()+e.breakerResetMs,l.fails=0),a instanceof b)throw $({remote:e.name,error:a}),a;if(a?.code)throw $({remote:e.name,error:a}),a;let p=new b(S.REMOTE_LOAD_FAILED,String(a?.message??a),{remote:e.name});throw $({remote:e.name,error:p}),p}}function U(e){let t=e.indexOf("/");return t===-1?{remote:e,module:""}:{remote:e.slice(0,t),module:H(e.slice(t+1))}}function H(e){return e?e.startsWith(".")?e:`./${e}`:""}async function re(e,t){let{remote:r,module:l}=U(e);try{w.beforeLoadRemote?.({remote:r,module:l})}catch(g){console.warn("[fulgurjs] beforeLoadRemote hook error (ignored):",g)}let h=i.get(r);if(!h)throw new b(S.REMOTE_UNKNOWN,`unknown remote "${r}". Register it via federation({ remotes }) or registerRemote().`,{remote:r});let a;try{let g=l&&h.manifestUrl?K(e):Promise.resolve();[a]=await Promise.all([V(h,{retries:t?.retries}),g])}catch(g){if(t?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,g),$({remote:r,error:g}),await t.fallbackModule();throw g}if(!l)return a;let p=`${r}@${h.shareScope||"default"}#${l}`;n.has(p)||n.set(p,a.get(l).catch(g=>{throw n.delete(p),g instanceof b||g?.code?g:new b(S.REMOTE_LOAD_FAILED,`failed to load module "${l}" from remote "${r}": ${String(g?.message??g)}`,{remote:r,module:l})}));let d;try{d=await n.get(p)}catch(g){if(t?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,g),$({remote:r,error:g}),await t.fallbackModule();throw g}try{w.afterLoadRemote?.({remote:r,module:l,module_ns:d})}catch(g){console.warn("[fulgurjs] afterLoadRemote hook error (ignored):",g)}if(d&&typeof d=="object"&&Object.keys(d).length===0){let g=new b(S.EMPTY_EXPORTS,`no exports: ${l} @ ${r}`,{remote:r,module:l});$({remote:r,error:g}),console.error(`[fulgurjs:MFU-009] ${g.message}`)}return d}function te(e){let t=i.get(e);if(!t)throw new b(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return V(t)}async function K(e,t={}){let{remote:r,module:l}=U(e),h=i.get(r);if(!h)throw new b(S.REMOTE_UNKNOWN,`unknown remote "${r}"`,{remote:r});let a=t.mode??"preload",p=(m,E)=>{if(m.sheet)return Promise.resolve();let c=y.get(m);if(c)return c;let u=new Promise(k=>{let v=()=>{m.removeEventListener("load",v),m.removeEventListener("error",O),k()},O=()=>{$({remote:r,error:new b(S.PRELOAD_FAILED,`failed to load remote stylesheet ${E}`,{remote:r})}),v()};m.addEventListener("load",v,{once:!0}),m.addEventListener("error",O,{once:!0}),m.sheet&&v()});return y.set(m,u),u},d=(m,E)=>{if(typeof document>"u")return Promise.resolve();let c=document.querySelector(`link[href="${m}"]`);if(c)return E==="style"&&a==="preload"?y.get(c)??Promise.resolve():Promise.resolve();let u=document.createElement("link");u.rel=E==="style"?"stylesheet":"modulepreload",u.href=m,a==="prefetch"&&(u.fetchPriority="low");let k=E==="style"?p(u,m):Promise.resolve();return document.head.appendChild(u),E==="style"&&a==="preload"?k:Promise.resolve()},g=m=>{let E=typeof document<"u"?document.baseURI:void 0,c=new URL(h.entry,E||"http://fulgurjs.invalid/");return!c.pathname.endsWith("/")&&!c.pathname.split("/").pop().includes(".")&&(c.pathname+="/"),new URL(m,c).href};try{if(h.manifestUrl){let m=f.get(h.manifestUrl);m||(m=fetch(h.manifestUrl,{cache:"no-cache",signal:AbortSignal.timeout(8e3)}).then(c=>c.ok?c.json():void 0),f.set(h.manifestUrl,m),m.then(c=>{c||f.delete(h.manifestUrl)},()=>f.delete(h.manifestUrl)));let E=await m;if(E){let c=E.schemaVersion;if(typeof c=="number"&&(!Number.isInteger(c)||c>1)){$({remote:r,error:new b(S.PRELOAD_FAILED,`unsupported manifest schemaVersion ${String(c)} (expected 1)`,{remote:r})}),await d(h.entry,"modulepreload");return}await d(h.entry,"modulepreload");let u=E.exposes,k=Array.isArray(u)?u.filter(_=>_&&typeof _=="object").map(_=>[String(_.name??""),_]):u&&typeof u=="object"?Object.entries(u):[],v=l?k.filter(([_,L])=>H(String(L?.name??_))===l):k,O=[];for(let[,_]of v)if(typeof _?.file=="string"&&await d(g(_.file),"modulepreload"),Array.isArray(_?.css))for(let L of _.css){if(typeof L!="string")continue;let ne=d(g(L),"style");a==="preload"&&O.push(ne)}await Promise.all(O);return}}await d(h.entry,"modulepreload")}catch(m){$({remote:r,error:new b(S.PRELOAD_FAILED,String(m?.message??m),{remote:r})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=o,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[t,r]of i)e[t]={...r.debug,entry:r.entry};return e},errors:[]}),{shareScopeMap:o,initSharing:B,registerShare:J,registerRemotes:F,registerRemote:X,registerPlugins:Y,loadShare:Z,loadRemote:re,getContainer:te,preloadRemote:K,parseSpec:U}}var W=globalThis,M=W.__FULGURJS_RUNTIME__??Ee();W.__FULGURJS_RUNTIME__=M;try{Object.freeze(M)}catch{}var _e=q;function ke(){return M}var je=M.initSharing,Oe=M.registerShare,Te=M.registerRemotes,Le=M.registerRemote,Ie=M.registerPlugins,Pe=M.loadShare,Ne=M.loadRemote,Ae=M.getContainer,Ue=M.preloadRemote,xe=M.parseSpec,Fe=M.shareScopeMap;function Ce(o){if(o&&typeof o=="object"&&"default"in o){let i=o.default;return i!==void 0?i:o}return o}var De=M;export{De as default,Ae as getContainer,ke as getRuntime,je as initSharing,Ne as loadRemote,Pe as loadShare,xe as parseSpec,Ue as preloadRemote,Ie as registerPlugins,Le as registerRemote,Te as registerRemotes,Oe as registerShare,M as runtime,Fe as shareScopeMap,Ce as unwrapDefault,_e as version};\n';
|
|
1290
1645
|
|
|
1291
1646
|
// src/index.ts
|
|
1292
1647
|
function readRuntimeCode() {
|
|
@@ -1303,7 +1658,7 @@ function enumerateCjsExports(packageName, appRoot) {
|
|
|
1303
1658
|
if (cached) return cached;
|
|
1304
1659
|
let names = [];
|
|
1305
1660
|
try {
|
|
1306
|
-
const appRequire = createRequire2(
|
|
1661
|
+
const appRequire = createRequire2(path6.join(appRoot, "package.json"));
|
|
1307
1662
|
const mod = appRequire(packageName);
|
|
1308
1663
|
names = Object.keys(mod);
|
|
1309
1664
|
} catch {
|
|
@@ -1363,14 +1718,19 @@ function federation(options) {
|
|
|
1363
1718
|
entryInitInjected: /* @__PURE__ */ new Set(),
|
|
1364
1719
|
manualChunkGroups: /* @__PURE__ */ new Map(),
|
|
1365
1720
|
sharedClosureRoots: [],
|
|
1366
|
-
facadeDynamic: false
|
|
1721
|
+
facadeDynamic: false,
|
|
1722
|
+
transformedModules: /* @__PURE__ */ new Set()
|
|
1723
|
+
};
|
|
1724
|
+
const recordRewritten = (id) => {
|
|
1725
|
+
state.transformedModules.add(id);
|
|
1726
|
+
state.transformedModules.add(id.split("?")[0]);
|
|
1367
1727
|
};
|
|
1368
1728
|
const pre = {
|
|
1369
1729
|
name: "fulgurjs:core",
|
|
1370
1730
|
enforce: "pre",
|
|
1371
1731
|
async config(userConfig, env) {
|
|
1372
1732
|
state.command = env.command;
|
|
1373
|
-
const root =
|
|
1733
|
+
const root = path6.resolve(userConfig.root ?? process.cwd());
|
|
1374
1734
|
const normalized = normalizeOptions(options, root, env.command);
|
|
1375
1735
|
state.normalized = normalized;
|
|
1376
1736
|
const extra = {};
|
|
@@ -1415,10 +1775,34 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1415
1775
|
}
|
|
1416
1776
|
if (env.command === "serve") {
|
|
1417
1777
|
syncViteCacheMarker(root, normalized.pluginVersion, (msg) => console.warn(msg));
|
|
1778
|
+
const corsOption = normalized.devCorsOrigins && normalized.devCorsOrigins !== "*" ? { origin: normalized.devCorsOrigins } : true;
|
|
1418
1779
|
extra.server = {
|
|
1419
1780
|
...userConfig.server ?? {},
|
|
1420
|
-
cors: userConfig.server?.cors ??
|
|
1781
|
+
cors: userConfig.server?.cors ?? corsOption
|
|
1421
1782
|
};
|
|
1783
|
+
const host = userConfig.server?.host;
|
|
1784
|
+
if (isNonLoopbackHost(host)) {
|
|
1785
|
+
if (!normalized.devCorsOrigins || normalized.devCorsOrigins === "*") {
|
|
1786
|
+
console.warn(
|
|
1787
|
+
formatFulgurjsDiagnostic({
|
|
1788
|
+
code: "DEV-011",
|
|
1789
|
+
symptom: `server.host=${String(host)} \u975E loopback \u4E14 dev \u8DE8\u6E90\u7B56\u7565\u4E3A\u901A\u914D\uFF08*\uFF09\uFF1A\u4EFB\u4F55\u80FD\u8BBF\u95EE\u8BE5\u673A\u7684\u6765\u6E90\u90FD\u53EF\u62C9\u53D6\u672C\u5E94\u7528\u8054\u90A6\u7AEF\u70B9\u4E0E\u6E90\u7801\u6A21\u5757`,
|
|
1790
|
+
cause: "devCorsOrigins \u672A\u914D\u7F6E\u65F6\u4FDD\u6301\u73B0\u72B6\u517C\u5BB9\uFF08*\uFF09\uFF1B\u8DE8\u673A\u5F00\u53D1\u66B4\u9732\u9762\u968F\u4E4B\u6269\u5927",
|
|
1791
|
+
fix: `\u6309\u5BBF\u4E3B\u6765\u6E90\u663E\u5F0F\u6536\u7D27\uFF1AdevCorsOrigins: ['http://<host>:<port>', ...]\uFF08\u6216\u786E\u8BA4\u8BE5\u673A\u5904\u4E8E\u53EF\u4FE1\u7F51\u7EDC\uFF09`
|
|
1792
|
+
})
|
|
1793
|
+
);
|
|
1794
|
+
}
|
|
1795
|
+
if (normalized.devFsRoot) {
|
|
1796
|
+
console.warn(
|
|
1797
|
+
formatFulgurjsDiagnostic({
|
|
1798
|
+
code: "DEV-012",
|
|
1799
|
+
symptom: `server.host=${String(host)} \u975E loopback \u4E14 dev manifest \u643A\u5E26 fsRoot\uFF08remote \u6839\u76EE\u5F55\u672C\u673A\u7EDD\u5BF9\u8DEF\u5F84\uFF09`,
|
|
1800
|
+
cause: "fsRoot \u4F9B\u540C\u673A\u8054\u8C03\u7684\u5BBF\u4E3B dts \u7C7B\u578B\u76F4\u8FDE\uFF1B2.x \u9ED8\u8BA4 true \u4FDD\u6301\u73B0\u72B6\uFF0C\u4E0B\u4E2A\u4E3B\u7248\u672C\u62DF\u6539\u4E3A\u663E\u5F0F\u5F00\u542F",
|
|
1801
|
+
fix: `\u540C\u673A\u8054\u8C03\u65E0\u9700\u52A8\u4F5C\uFF1B\u8DE8\u673A/\u4E0D\u53EF\u4FE1\u7F51\u7EDC\u53EF devFsRoot: false\uFF08\u5BBF\u4E3B dts \u5C06\u964D\u7EA7\u4E3A any \u6869\u5E76\u6709\u660E\u786E\u63D0\u793A\uFF09`
|
|
1802
|
+
})
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1422
1806
|
} else {
|
|
1423
1807
|
const userTarget = userConfig.build?.target;
|
|
1424
1808
|
if (userTarget) {
|
|
@@ -1433,6 +1817,12 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1433
1817
|
}
|
|
1434
1818
|
if (normalized.remotes.length > 0 && normalized.devSharedSelf) {
|
|
1435
1819
|
state.facadeDynamic = true;
|
|
1820
|
+
const userMc = userConfig.build?.rollupOptions?.output?.manualChunks;
|
|
1821
|
+
debugLog("facade", {
|
|
1822
|
+
stage: "config",
|
|
1823
|
+
facadeDynamic: true,
|
|
1824
|
+
manualChunks: Array.isArray(userConfig.build?.rollupOptions?.output) ? "array" : typeof userMc
|
|
1825
|
+
});
|
|
1436
1826
|
const userOutput = userConfig.build?.rollupOptions?.output;
|
|
1437
1827
|
if (Array.isArray(userOutput)) {
|
|
1438
1828
|
console.warn(
|
|
@@ -1500,7 +1890,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1500
1890
|
}
|
|
1501
1891
|
}
|
|
1502
1892
|
},
|
|
1503
|
-
resolveId(source) {
|
|
1893
|
+
resolveId(source, importer) {
|
|
1504
1894
|
let s = source;
|
|
1505
1895
|
if (s.startsWith("/@id/")) s = s.slice(5);
|
|
1506
1896
|
if (s.startsWith("__x00__")) s = "\0" + s.slice(7);
|
|
@@ -1508,8 +1898,18 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1508
1898
|
const bare = q === -1 ? s : s.slice(0, q);
|
|
1509
1899
|
const query = q === -1 ? "" : s.slice(q);
|
|
1510
1900
|
const bareClean = bare.startsWith("\0") ? bare.slice(1) : bare;
|
|
1901
|
+
if (state.normalized && importer) {
|
|
1902
|
+
const impClean = importer.split("?")[0];
|
|
1903
|
+
const isOurVirtual = impClean.startsWith("virtual:fulgurjs-") || impClean.startsWith("\0virtual:fulgurjs-");
|
|
1904
|
+
if (!isOurVirtual && !impClean.includes("/node_modules/.vite/") && !state.sharedClosureRoots.some((r) => impClean.startsWith(r.root)) && (state.transformedModules.has(importer) || state.transformedModules.has(impClean))) {
|
|
1905
|
+
const hit = state.normalized.shared.find((sh) => sh.aliases.includes(bareClean));
|
|
1906
|
+
if (hit) {
|
|
1907
|
+
return RESOLVED.sharedNsFacade(hit.shareKey) + query;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1511
1911
|
const n = state.normalized;
|
|
1512
|
-
if (n && !
|
|
1912
|
+
if (n && !bare.startsWith("\0") && !bareClean.startsWith(".") && !bareClean.startsWith("/") && !bareClean.startsWith("virtual:")) {
|
|
1513
1913
|
const slash = bareClean.indexOf("/");
|
|
1514
1914
|
if (slash > 0) {
|
|
1515
1915
|
const prefix = bareClean.slice(0, slash);
|
|
@@ -1526,6 +1926,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1526
1926
|
if (bareClean === RUNTIME_PROXY_VIRTUAL_ID) return RESOLVED.runtimeProxy;
|
|
1527
1927
|
if (bareClean === INIT_VIRTUAL_ID) return RESOLVED.init;
|
|
1528
1928
|
if (bareClean === "virtual:fulgurjs-remote-schema") return bareClean;
|
|
1929
|
+
if (bareClean === "virtual:fulgurjs-api") return bareClean;
|
|
1529
1930
|
if (bareClean === "virtual:fulgurjs-provides") return RESOLVED.provides;
|
|
1530
1931
|
if (bareClean === "virtual:fulgurjs-remote-entry") return RESOLVED.remoteEntry;
|
|
1531
1932
|
if (bareClean.startsWith(SHARED_NS_FACADE_PREFIX)) {
|
|
@@ -1552,6 +1953,9 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1552
1953
|
if (clean === "virtual:fulgurjs-provides" && state.normalized) {
|
|
1553
1954
|
return genDevProvides(state.normalized);
|
|
1554
1955
|
}
|
|
1956
|
+
if (clean === "virtual:fulgurjs-api") {
|
|
1957
|
+
return genApiFacade();
|
|
1958
|
+
}
|
|
1555
1959
|
if (clean === "virtual:fulgurjs-remote-schema" && state.normalized) {
|
|
1556
1960
|
if (state.command === "build") return genEmptyRemoteSchemaModule();
|
|
1557
1961
|
remoteSchemaPromise ??= probeRemotesAndBuildSchema(state.normalized).then(
|
|
@@ -1619,6 +2023,7 @@ ${code}`, map: null };
|
|
|
1619
2023
|
if (/\.vue(\?|$)/.test(id)) {
|
|
1620
2024
|
if (state.command === "build" && /type=script/.test(id)) {
|
|
1621
2025
|
return transformModule(code, id, {
|
|
2026
|
+
onRewrite: () => recordRewritten(id),
|
|
1622
2027
|
options: state.normalized,
|
|
1623
2028
|
rewriteShared: true,
|
|
1624
2029
|
allowNodeModules,
|
|
@@ -1630,6 +2035,10 @@ ${code}`, map: null };
|
|
|
1630
2035
|
}
|
|
1631
2036
|
if (!isTransformableId(id, allowNodeModules)) return null;
|
|
1632
2037
|
return transformModule(code, id, {
|
|
2038
|
+
onRewrite: () => {
|
|
2039
|
+
debugLog("transform", { stage: "pre", mode: state.command, module: redactModulePath(id, state.normalized.root) });
|
|
2040
|
+
recordRewritten(id);
|
|
2041
|
+
},
|
|
1633
2042
|
options: state.normalized,
|
|
1634
2043
|
// build:全量改写;dev:默认仅纯 remote 改写 shared(被宿主消费的组件需协商到宿主实例),
|
|
1635
2044
|
// 双角色宿主可显式 devSharedSelf: true 参与协商
|
|
@@ -1652,7 +2061,7 @@ ${code}`, map: null };
|
|
|
1652
2061
|
for (const tag of html.match(moduleScriptRe) ?? []) {
|
|
1653
2062
|
const src = srcRe.exec(tag)?.[1];
|
|
1654
2063
|
if (!src || src.startsWith("http") || src.startsWith("//")) continue;
|
|
1655
|
-
const abs =
|
|
2064
|
+
const abs = path6.resolve(state.normalized.root, src.startsWith("/") ? src.slice(1) : src);
|
|
1656
2065
|
state.entryAbsPaths.add(abs);
|
|
1657
2066
|
}
|
|
1658
2067
|
return html;
|
|
@@ -1664,7 +2073,7 @@ ${code}`, map: null };
|
|
|
1664
2073
|
if (state.manualChunkSpecsPending) {
|
|
1665
2074
|
for (const [group, specifier] of state.manualChunkSpecsPending) {
|
|
1666
2075
|
try {
|
|
1667
|
-
const r = await this.resolve(specifier,
|
|
2076
|
+
const r = await this.resolve(specifier, path6.join(n.root, "index.html"));
|
|
1668
2077
|
if (r?.id) {
|
|
1669
2078
|
state.manualChunkGroups.set(r.id, group);
|
|
1670
2079
|
state.manualChunkGroups.set(r.id.split("?")[0], group);
|
|
@@ -1694,7 +2103,7 @@ ${code}`, map: null };
|
|
|
1694
2103
|
};
|
|
1695
2104
|
for (const item of n.shared) {
|
|
1696
2105
|
if (item.import === false) continue;
|
|
1697
|
-
const selfFile = await this.resolve(item.import,
|
|
2106
|
+
const selfFile = await this.resolve(item.import, path6.join(n.root, "index.html")).then(
|
|
1698
2107
|
(r) => r?.id?.split("?")[0] ?? null
|
|
1699
2108
|
).catch(() => null);
|
|
1700
2109
|
for (const alias of item.aliases) {
|
|
@@ -1709,7 +2118,7 @@ ${code}`, map: null };
|
|
|
1709
2118
|
}
|
|
1710
2119
|
}
|
|
1711
2120
|
if (!file) {
|
|
1712
|
-
file = await this.resolve(alias,
|
|
2121
|
+
file = await this.resolve(alias, path6.join(n.root, "index.html")).then(
|
|
1713
2122
|
(r) => r?.id?.split("?")[0] ?? null
|
|
1714
2123
|
).catch(() => null);
|
|
1715
2124
|
}
|
|
@@ -1722,10 +2131,17 @@ ${code}`, map: null };
|
|
|
1722
2131
|
}
|
|
1723
2132
|
}
|
|
1724
2133
|
state.sharedClosureRoots = [...rootKeys.entries()].map(([root, keys]) => ({ root, keys }));
|
|
2134
|
+
if (state.sharedClosureRoots.length > 0) {
|
|
2135
|
+
debugLog("facade", {
|
|
2136
|
+
stage: "buildStart",
|
|
2137
|
+
sharedClosureRoots: state.sharedClosureRoots.length,
|
|
2138
|
+
keys: [...new Set(state.sharedClosureRoots.flatMap((r) => [...r.keys]))]
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
1725
2141
|
}
|
|
1726
2142
|
if (n.exposes.length > 0) {
|
|
1727
2143
|
for (const e of n.exposes) {
|
|
1728
|
-
const resolved = await this.resolve(e.import,
|
|
2144
|
+
const resolved = await this.resolve(e.import, path6.join(n.root, "index.html"));
|
|
1729
2145
|
if (resolved) {
|
|
1730
2146
|
state.exposeAbsPaths[e.import] = resolved.id.split("?")[0];
|
|
1731
2147
|
} else {
|
|
@@ -1740,33 +2156,55 @@ ${code}`, map: null };
|
|
|
1740
2156
|
});
|
|
1741
2157
|
}
|
|
1742
2158
|
},
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2159
|
+
generateBundle: {
|
|
2160
|
+
order: "post",
|
|
2161
|
+
handler(_opts, bundle) {
|
|
2162
|
+
const n = state.normalized;
|
|
2163
|
+
if (state.command !== "build" || !n || n.exposes.length === 0 || !n.manifest) return;
|
|
2164
|
+
const collectStaticCss = (entryFile) => {
|
|
2165
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2166
|
+
const cssFiles = /* @__PURE__ */ new Set();
|
|
2167
|
+
const visit = (fileName) => {
|
|
2168
|
+
if (visited.has(fileName)) return;
|
|
2169
|
+
visited.add(fileName);
|
|
2170
|
+
const chunk = bundle[fileName];
|
|
2171
|
+
if (!chunk || chunk.type !== "chunk") return;
|
|
2172
|
+
const viteMeta = chunk.viteMetadata;
|
|
2173
|
+
for (const css of viteMeta?.importedCss ?? []) cssFiles.add(css);
|
|
2174
|
+
for (const importedFile of chunk.imports) visit(importedFile);
|
|
1755
2175
|
};
|
|
2176
|
+
visit(entryFile);
|
|
2177
|
+
return [...cssFiles];
|
|
2178
|
+
};
|
|
2179
|
+
const facadeToChunk = {};
|
|
2180
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2181
|
+
if (chunk.type !== "chunk") continue;
|
|
2182
|
+
const facade = chunk.facadeModuleId?.split("?")[0];
|
|
2183
|
+
if (facade) {
|
|
2184
|
+
facadeToChunk[facade] = {
|
|
2185
|
+
file: fileName,
|
|
2186
|
+
css: collectStaticCss(fileName)
|
|
2187
|
+
};
|
|
2188
|
+
}
|
|
1756
2189
|
}
|
|
2190
|
+
for (const e of n.exposes) {
|
|
2191
|
+
const abs = state.exposeAbsPaths[e.import];
|
|
2192
|
+
const hit = abs ? facadeToChunk[abs] : void 0;
|
|
2193
|
+
if (hit) state.exposeFiles[e.name] = hit;
|
|
2194
|
+
}
|
|
2195
|
+
const entryChunkName = Object.keys(bundle).find((k) => bundle[k].type === "chunk" && k === n.filename);
|
|
2196
|
+
const manifest = genProdManifest(n, state.exposeFiles, entryChunkName ?? n.filename);
|
|
2197
|
+
debugLog("manifest", {
|
|
2198
|
+
stage: "generateBundle",
|
|
2199
|
+
exposes: Object.keys(state.exposeFiles).length,
|
|
2200
|
+
exposesWithCss: Object.values(state.exposeFiles).filter((e) => e.css.length > 0).length
|
|
2201
|
+
});
|
|
2202
|
+
this.emitFile({
|
|
2203
|
+
type: "asset",
|
|
2204
|
+
fileName: "fulgurjs-manifest.json",
|
|
2205
|
+
source: JSON.stringify(manifest, null, 2)
|
|
2206
|
+
});
|
|
1757
2207
|
}
|
|
1758
|
-
for (const e of n.exposes) {
|
|
1759
|
-
const abs = state.exposeAbsPaths[e.import];
|
|
1760
|
-
const hit = abs ? facadeToChunk[abs] : void 0;
|
|
1761
|
-
if (hit) state.exposeFiles[e.name] = hit;
|
|
1762
|
-
}
|
|
1763
|
-
const entryChunkName = Object.keys(bundle).find((k) => bundle[k].type === "chunk" && k === n.filename);
|
|
1764
|
-
const manifest = genProdManifest(n, state.exposeFiles, entryChunkName ?? n.filename);
|
|
1765
|
-
this.emitFile({
|
|
1766
|
-
type: "asset",
|
|
1767
|
-
fileName: "fulgurjs-manifest.json",
|
|
1768
|
-
source: JSON.stringify(manifest, null, 2)
|
|
1769
|
-
});
|
|
1770
2208
|
},
|
|
1771
2209
|
configureServer(server) {
|
|
1772
2210
|
const n = state.normalized;
|
|
@@ -1788,7 +2226,10 @@ ${code}`, map: null };
|
|
|
1788
2226
|
const raw = (req.url ?? "").split("?")[0];
|
|
1789
2227
|
const stripped = raw.startsWith(baseNorm) ? `/${raw.slice(baseNorm.length)}` : raw;
|
|
1790
2228
|
if (stripped === "/@fulgurjs-entry.js" || stripped === "/@fulgurjs-manifest.json") {
|
|
1791
|
-
|
|
2229
|
+
const origin = Array.isArray(req.headers.origin) ? req.headers.origin[0] : req.headers.origin;
|
|
2230
|
+
for (const [k, v] of Object.entries(corsHeadersFor(origin, n.devCorsOrigins))) {
|
|
2231
|
+
res.setHeader(k, v);
|
|
2232
|
+
}
|
|
1792
2233
|
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
|
|
1793
2234
|
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
1794
2235
|
if (req.method === "OPTIONS") {
|
|
@@ -1852,7 +2293,7 @@ ${code}`, map: null };
|
|
|
1852
2293
|
if (state.command === "serve" && code.includes("virtual:fulgurjs-runtime") && !code.includes("virtual:fulgurjs-runtime-proxy") && isExposeTargetFile(clean, state.normalized.root, state.normalized.exposes)) {
|
|
1853
2294
|
return { code: code.split("virtual:fulgurjs-runtime").join("virtual:fulgurjs-runtime-proxy"), map: null };
|
|
1854
2295
|
}
|
|
1855
|
-
if (isPluginProcessedModule(code)) return null;
|
|
2296
|
+
if (state.command === "serve" && isPluginProcessedModule(code)) return null;
|
|
1856
2297
|
if (/type=(style|template)/.test(id)) return null;
|
|
1857
2298
|
const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
|
|
1858
2299
|
if (!isJsLike) return null;
|
|
@@ -1861,20 +2302,11 @@ ${code}`, map: null };
|
|
|
1861
2302
|
if (state.command === "serve" && clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) {
|
|
1862
2303
|
return null;
|
|
1863
2304
|
}
|
|
1864
|
-
if (state.command === "build"
|
|
1865
|
-
|
|
1866
|
-
if (!quickCheck) return null;
|
|
1867
|
-
const allowNodeModules = isPureRemoteBuild;
|
|
1868
|
-
return transformModule(code, id, {
|
|
1869
|
-
options: state.normalized,
|
|
1870
|
-
rewriteShared: true,
|
|
1871
|
-
allowNodeModules,
|
|
1872
|
-
sharedClosureRoots: state.sharedClosureRoots
|
|
1873
|
-
});
|
|
2305
|
+
if (state.command === "build") {
|
|
2306
|
+
return buildFallbackTransform(code, id);
|
|
1874
2307
|
}
|
|
1875
|
-
const rewriteShared = state.
|
|
2308
|
+
const rewriteShared = state.normalized.devSharedSelf;
|
|
1876
2309
|
const remapSpecifier = (spec) => {
|
|
1877
|
-
if (state.normalized.shared.some((s) => s.aliases.includes(spec))) return spec;
|
|
1878
2310
|
const depMatch = spec.match(/\/node_modules\/\.vite\/deps\/([^/?]+)\.js/);
|
|
1879
2311
|
if (depMatch) {
|
|
1880
2312
|
const depName = depMatch[1];
|
|
@@ -1886,10 +2318,10 @@ ${code}`, map: null };
|
|
|
1886
2318
|
return state.resolvedSharedPaths.get(cleanPath) ?? null;
|
|
1887
2319
|
};
|
|
1888
2320
|
return transformModule(code, id, {
|
|
2321
|
+
onRewrite: () => recordRewritten(id),
|
|
1889
2322
|
options: state.normalized,
|
|
1890
2323
|
remapSpecifier,
|
|
1891
2324
|
rewriteShared,
|
|
1892
|
-
allowNodeModules: state.command === "build" ? isPureRemoteBuild || state.normalized.devSharedSelf : void 0,
|
|
1893
2325
|
sharedClosureRoots: state.sharedClosureRoots
|
|
1894
2326
|
});
|
|
1895
2327
|
}
|
|
@@ -1899,12 +2331,32 @@ ${code}`, map: null };
|
|
|
1899
2331
|
if (!n) return;
|
|
1900
2332
|
for (const s of n.shared) {
|
|
1901
2333
|
if (s.import === false) continue;
|
|
1902
|
-
void server.pluginContainer.resolveId(s.import,
|
|
2334
|
+
void server.pluginContainer.resolveId(s.import, path6.join(n.root, "index.html")).then((r) => {
|
|
1903
2335
|
if (r?.id) state.resolvedSharedPaths.set(r.id.split("?")[0], s.configKey);
|
|
1904
2336
|
}).catch(() => {
|
|
1905
2337
|
});
|
|
1906
2338
|
}
|
|
1907
2339
|
}
|
|
2340
|
+
async function buildFallbackTransform(code, id) {
|
|
2341
|
+
if (/type=(style|template)/.test(id)) return null;
|
|
2342
|
+
const clean = id.split("?")[0];
|
|
2343
|
+
const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
|
|
2344
|
+
if (!isJsLike) return null;
|
|
2345
|
+
const quickCheck = /require\s*\(\s*["']|(?:from|import)\s*["']/.test(code);
|
|
2346
|
+
if (!quickCheck) return null;
|
|
2347
|
+
const n = state.normalized;
|
|
2348
|
+
const isPureRemoteBuild = n.exposes.length > 0 && n.remotes.length === 0;
|
|
2349
|
+
return transformModule(code, id, {
|
|
2350
|
+
onRewrite: () => {
|
|
2351
|
+
debugLog("transform", { stage: "post-fallback", mode: "build", module: redactModulePath(id, n.root) });
|
|
2352
|
+
recordRewritten(id);
|
|
2353
|
+
},
|
|
2354
|
+
options: n,
|
|
2355
|
+
rewriteShared: true,
|
|
2356
|
+
allowNodeModules: isPureRemoteBuild || n.devSharedSelf,
|
|
2357
|
+
sharedClosureRoots: state.sharedClosureRoots
|
|
2358
|
+
});
|
|
2359
|
+
}
|
|
1908
2360
|
return [pre, post];
|
|
1909
2361
|
}
|
|
1910
2362
|
var index_default = federation;
|