@fulgurjs/federation 0.4.2 → 0.5.1
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 +30 -7
- package/DESIGN.md +8 -8
- package/README.md +55 -55
- package/dist/cli.js +43 -43
- package/dist/config.cjs +13 -13
- package/dist/config.d.cts +20 -20
- package/dist/config.d.ts +20 -20
- package/dist/config.js +11 -11
- package/dist/index.cjs +524 -518
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +524 -518
- package/dist/pages.cjs +9 -9
- package/dist/pages.d.cts +7 -7
- package/dist/pages.d.ts +7 -7
- package/dist/pages.js +7 -7
- package/dist/runtime.js +2 -2
- package/docs/manual.html +23 -23
- package/docs/webpack-mf-/345/257/271/347/205/247/344/270/216/347/274/272/345/217/243.md +1 -1
- package/docs//346/262/231/347/256/261/350/276/271/347/225/214/345/256/241/350/256/241.md +1 -1
- package/docs//350/277/201/347/247/273/346/214/207/345/215/227.md +8 -8
- package/examples/fulgur.config.example.ts +4 -4
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -8,25 +8,25 @@ import fs from "fs";
|
|
|
8
8
|
import path from "path";
|
|
9
9
|
|
|
10
10
|
// src/version.ts
|
|
11
|
-
var RUNTIME_VERSION = "0.
|
|
11
|
+
var RUNTIME_VERSION = "0.5.1";
|
|
12
12
|
|
|
13
13
|
// src/options.ts
|
|
14
|
-
var DEFAULT_FILENAME = "
|
|
15
|
-
var RUNTIME_VIRTUAL_ID = "virtual:
|
|
16
|
-
var RUNTIME_PROXY_VIRTUAL_ID = "virtual:
|
|
17
|
-
var INIT_VIRTUAL_ID = "virtual:
|
|
18
|
-
var SHARED_FACADE_PREFIX = "virtual:
|
|
19
|
-
var SHARED_NS_FACADE_PREFIX = "virtual:
|
|
14
|
+
var DEFAULT_FILENAME = "fulgurjs-remoteEntry.js";
|
|
15
|
+
var RUNTIME_VIRTUAL_ID = "virtual:fulgurjs-runtime";
|
|
16
|
+
var RUNTIME_PROXY_VIRTUAL_ID = "virtual:fulgurjs-runtime-proxy";
|
|
17
|
+
var INIT_VIRTUAL_ID = "virtual:fulgurjs-init";
|
|
18
|
+
var SHARED_FACADE_PREFIX = "virtual:fulgurjs-shared:";
|
|
19
|
+
var SHARED_NS_FACADE_PREFIX = "virtual:fulgurjs-shared-ns:";
|
|
20
20
|
var RESOLVED = {
|
|
21
|
-
runtime: "virtual:
|
|
22
|
-
runtimeProxy: "virtual:
|
|
23
|
-
init: "virtual:
|
|
24
|
-
provides: "virtual:
|
|
25
|
-
remoteEntry: "virtual:
|
|
26
|
-
sharedFacade: (name) => `virtual:
|
|
27
|
-
sharedNsFacade: (name) => `virtual:
|
|
21
|
+
runtime: "virtual:fulgurjs-runtime",
|
|
22
|
+
runtimeProxy: "virtual:fulgurjs-runtime-proxy",
|
|
23
|
+
init: "virtual:fulgurjs-init",
|
|
24
|
+
provides: "virtual:fulgurjs-provides",
|
|
25
|
+
remoteEntry: "virtual:fulgurjs-remote-entry",
|
|
26
|
+
sharedFacade: (name) => `virtual:fulgurjs-shared:${name}`,
|
|
27
|
+
sharedNsFacade: (name) => `virtual:fulgurjs-shared-ns:${name}`,
|
|
28
28
|
/** CJS require(<shared>) 垫片:与 sharedNsFacade 同体,仅 id 形态不同(保持 require 调用语义) */
|
|
29
|
-
cjsNsFacade: (name) => `virtual:
|
|
29
|
+
cjsNsFacade: (name) => `virtual:fulgurjs-cjs-ns:${name}`
|
|
30
30
|
};
|
|
31
31
|
function joinUrl(base, file) {
|
|
32
32
|
const b = base.endsWith("/") ? base : `${base}/`;
|
|
@@ -64,7 +64,7 @@ function normalizeRemoteValue(key, value, filename, warnings) {
|
|
|
64
64
|
if (mode === "prod") return rawUrl;
|
|
65
65
|
return rawUrl;
|
|
66
66
|
}
|
|
67
|
-
return joinUrl(rawUrl, mode === "dev" ? "@
|
|
67
|
+
return joinUrl(rawUrl, mode === "dev" ? "@fulgurjs-entry.js" : filename);
|
|
68
68
|
};
|
|
69
69
|
const explicitDev = cfg.dev;
|
|
70
70
|
const explicitProd = cfg.prod;
|
|
@@ -195,7 +195,7 @@ function configError(what, got, expect, example) {
|
|
|
195
195
|
const gotText = typeof got === "string" ? `"${got}"` : JSON.stringify(got);
|
|
196
196
|
throw new Error(
|
|
197
197
|
[
|
|
198
|
-
`[
|
|
198
|
+
`[fulgurjs] Invalid federation() config \u2014 ${what}`,
|
|
199
199
|
` got: ${gotText}`,
|
|
200
200
|
` expected: ${expect}`,
|
|
201
201
|
` example: ${example}`
|
|
@@ -287,7 +287,7 @@ function validateOptions(options) {
|
|
|
287
287
|
function normalizeOptions(options, root, command) {
|
|
288
288
|
const warnings = [];
|
|
289
289
|
validateOptions(options);
|
|
290
|
-
if (!options.name) throw new Error("[
|
|
290
|
+
if (!options.name) throw new Error("[fulgurjs] option `name` is required.");
|
|
291
291
|
if (options.remoteType && options.remoteType !== "module") {
|
|
292
292
|
warnings.push(
|
|
293
293
|
`remoteType "${options.remoteType}" requires webpack-host interop (P3 milestone); falling back to "module".`
|
|
@@ -300,7 +300,7 @@ function normalizeOptions(options, root, command) {
|
|
|
300
300
|
}
|
|
301
301
|
if (options.automaticAsyncBoundary === false) {
|
|
302
302
|
warnings.push(
|
|
303
|
-
"automaticAsyncBoundary=false has no effect:
|
|
303
|
+
"automaticAsyncBoundary=false has no effect: fulgurjs uses TLA-based automatic async boundaries (better than webpack manual bootstrap)."
|
|
304
304
|
);
|
|
305
305
|
}
|
|
306
306
|
const exposes = [];
|
|
@@ -362,126 +362,462 @@ function normalizeOptions(options, root, command) {
|
|
|
362
362
|
import { init as initLexer, parse } from "es-module-lexer";
|
|
363
363
|
import MagicString from "magic-string";
|
|
364
364
|
import path2 from "path";
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
return
|
|
369
|
-
}
|
|
370
|
-
function isExposeTargetFile(cleanPath, root, exposes) {
|
|
371
|
-
for (const e of exposes) {
|
|
372
|
-
const abs = path2.resolve(root, e.import.replace(/^\.\//, ""));
|
|
373
|
-
if (cleanPath === abs) return true;
|
|
374
|
-
for (const ext of [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".vue"]) {
|
|
375
|
-
if (cleanPath === abs + ext) return true;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
return false;
|
|
365
|
+
|
|
366
|
+
// src/virtual.ts
|
|
367
|
+
function jsonReplacer(_k, v) {
|
|
368
|
+
return v;
|
|
379
369
|
}
|
|
380
|
-
function
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
370
|
+
function genSharedFacade(specifier, exportNames) {
|
|
371
|
+
const names = (exportNames ?? []).filter(
|
|
372
|
+
(n) => n !== "default" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(n)
|
|
373
|
+
);
|
|
374
|
+
if (names.length === 0) {
|
|
375
|
+
return [
|
|
376
|
+
`import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
|
|
377
|
+
`export * from ${JSON.stringify(specifier)};`,
|
|
378
|
+
`export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
|
|
379
|
+
""
|
|
380
|
+
].join("\n");
|
|
388
381
|
}
|
|
389
|
-
return
|
|
382
|
+
return [
|
|
383
|
+
`import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
|
|
384
|
+
...names.map((n) => `export const ${n} = __fulgurjs_facade[${JSON.stringify(n)}];`),
|
|
385
|
+
`export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
|
|
386
|
+
""
|
|
387
|
+
].join("\n");
|
|
390
388
|
}
|
|
391
|
-
function
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
389
|
+
function genSharedNsFacade(item, loadShareCall, exportNames) {
|
|
390
|
+
const lines = [
|
|
391
|
+
`import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
|
|
392
|
+
`const __fulgurjs_m = await ${loadShareCall};`,
|
|
393
|
+
`const __fulgurjs_d = __fulgurjsU(__fulgurjs_m);`,
|
|
394
|
+
`export default __fulgurjs_d;`
|
|
395
|
+
];
|
|
396
|
+
const seen = /* @__PURE__ */ new Set(["default"]);
|
|
397
|
+
for (const name of exportNames) {
|
|
398
|
+
if (seen.has(name) || !/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) continue;
|
|
399
|
+
seen.add(name);
|
|
400
|
+
lines.push(`export const ${name} = __fulgurjs_d[${JSON.stringify(name)}];`);
|
|
396
401
|
}
|
|
397
|
-
|
|
402
|
+
lines.push("");
|
|
403
|
+
return lines.join("\n");
|
|
398
404
|
}
|
|
399
|
-
function
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const
|
|
408
|
-
|
|
405
|
+
function genBindingFacade(item, bindings, loadShareCall) {
|
|
406
|
+
const lines = [
|
|
407
|
+
`import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
|
|
408
|
+
`const __fulgurjs_m = await ${loadShareCall};`
|
|
409
|
+
];
|
|
410
|
+
const seen = /* @__PURE__ */ new Set();
|
|
411
|
+
for (const bRaw of bindings) {
|
|
412
|
+
if (bRaw === "default") continue;
|
|
413
|
+
const asMatch = bRaw.match(/^(.*?)\s+as\s+(.+)$/);
|
|
414
|
+
const imported = (asMatch ? asMatch[1] : bRaw).trim();
|
|
415
|
+
if (seen.has(imported)) continue;
|
|
416
|
+
seen.add(imported);
|
|
417
|
+
lines.push(`export const ${imported} = __fulgurjs_m.${imported};`);
|
|
409
418
|
}
|
|
410
|
-
|
|
419
|
+
lines.push(`export default __fulgurjsU(__fulgurjs_m);`);
|
|
420
|
+
lines.push("");
|
|
421
|
+
return lines.join("\n");
|
|
411
422
|
}
|
|
412
|
-
function
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const
|
|
421
|
-
|
|
423
|
+
function genRemoteBindingFacade(remoteSpec, bindings) {
|
|
424
|
+
const lines = [
|
|
425
|
+
`import { loadRemote as __fulgurjs_loadRemote, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
|
|
426
|
+
`const __fulgurjs_m = await __fulgurjs_loadRemote(${JSON.stringify(remoteSpec)});`
|
|
427
|
+
];
|
|
428
|
+
const seen = /* @__PURE__ */ new Set();
|
|
429
|
+
for (const bRaw of bindings) {
|
|
430
|
+
if (bRaw === "default") continue;
|
|
431
|
+
const asMatch = bRaw.match(/^(.*?)\s+as\s+(.+)$/);
|
|
432
|
+
const imported = (asMatch ? asMatch[1] : bRaw).trim();
|
|
433
|
+
if (seen.has(imported)) continue;
|
|
434
|
+
seen.add(imported);
|
|
435
|
+
lines.push(`export const ${imported} = __fulgurjs_m.${imported};`);
|
|
422
436
|
}
|
|
423
|
-
|
|
437
|
+
lines.push(`export default __fulgurjsU(__fulgurjs_m);`);
|
|
438
|
+
lines.push("");
|
|
439
|
+
return lines.join("\n");
|
|
424
440
|
}
|
|
425
|
-
function
|
|
426
|
-
return
|
|
441
|
+
function providesRecords(options) {
|
|
442
|
+
return options.shared.filter((s) => s.import !== false).map((s) => ({
|
|
443
|
+
shareScope: s.shareScope,
|
|
444
|
+
name: s.shareKey,
|
|
445
|
+
version: s.version,
|
|
446
|
+
eager: s.eager,
|
|
447
|
+
from: options.name
|
|
448
|
+
}));
|
|
427
449
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
450
|
+
var INIT_MODULE_MARKER = "/* fulgurjs:init */";
|
|
451
|
+
function genInitModule(options, command) {
|
|
452
|
+
const lines = [INIT_MODULE_MARKER];
|
|
453
|
+
lines.push(`import { initSharing, registerShare, registerRemotes, registerPlugins } from "virtual:fulgurjs-runtime";`);
|
|
454
|
+
const provides = providesRecords(options);
|
|
455
|
+
const eagerShared = options.shared.filter((s) => s.eager && s.import !== false);
|
|
456
|
+
eagerShared.forEach((s, i) => {
|
|
457
|
+
lines.push(`import * as __fulgurjs_eager_${i} from "virtual:fulgurjs-shared:${s.shareKey}";`);
|
|
458
|
+
});
|
|
459
|
+
const isDevHost = command === "serve" && options.remotes.length > 0;
|
|
460
|
+
const loadedFlag = isDevHost ? "true" : "false";
|
|
461
|
+
lines.push(`initSharing(${JSON.stringify(options.shareScope)});`);
|
|
462
|
+
if (options.runtimePlugins.length > 0) {
|
|
463
|
+
options.runtimePlugins.forEach((p, i) => {
|
|
464
|
+
lines.push(`import * as __fulgurjs_rp_${i} from ${JSON.stringify(p)};`);
|
|
465
|
+
});
|
|
466
|
+
lines.push(
|
|
467
|
+
`registerPlugins([${options.runtimePlugins.map((_, i) => `(__fulgurjs_rp_${i}.default ?? __fulgurjs_rp_${i})`).join(", ")}]);`
|
|
468
|
+
);
|
|
438
469
|
}
|
|
439
|
-
|
|
470
|
+
if (options.remotes.length > 0) {
|
|
471
|
+
lines.push(...registerRemotesLines(options, command));
|
|
472
|
+
}
|
|
473
|
+
provides.forEach((p) => {
|
|
474
|
+
const eagerIdx = eagerShared.findIndex((s) => s.shareKey === p.name && s.shareScope === p.shareScope);
|
|
475
|
+
if (p.eager && eagerIdx !== -1) {
|
|
476
|
+
lines.push(
|
|
477
|
+
`registerShare(${JSON.stringify(p.shareScope)}, ${JSON.stringify(p.name)}, ${JSON.stringify(p.version)}, () => Promise.resolve(__fulgurjs_eager_${eagerIdx}), { from: ${JSON.stringify(p.from)}, eager: true, loaded: ${loadedFlag} });`
|
|
478
|
+
);
|
|
479
|
+
} else {
|
|
480
|
+
lines.push(
|
|
481
|
+
`registerShare(${JSON.stringify(p.shareScope)}, ${JSON.stringify(p.name)}, ${JSON.stringify(p.version)}, () => import("virtual:fulgurjs-shared:${p.name}"), { from: ${JSON.stringify(p.from)}, eager: false, loaded: ${loadedFlag} });`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
return `${lines.join("\n")}
|
|
486
|
+
`;
|
|
440
487
|
}
|
|
441
|
-
function
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
488
|
+
function manifestUrlFor(r, command) {
|
|
489
|
+
const entry = command === "serve" ? r.devEntry : r.prodEntry;
|
|
490
|
+
if (!entry) return null;
|
|
491
|
+
try {
|
|
492
|
+
const u = new URL(entry);
|
|
493
|
+
if (u.pathname.includes("@fulgurjs-entry.js")) {
|
|
494
|
+
u.pathname = u.pathname.replace("@fulgurjs-entry.js", "@fulgurjs-manifest.json");
|
|
495
|
+
} else {
|
|
496
|
+
u.pathname = u.pathname.replace(/[^/]*$/, "") + "fulgurjs-manifest.json";
|
|
497
|
+
}
|
|
498
|
+
return u.href;
|
|
499
|
+
} catch {
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
450
502
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
503
|
+
function registerRemotesLines(options, command) {
|
|
504
|
+
if (options.remotes.length === 0) return [];
|
|
505
|
+
const remotesJson = options.remotes.filter((r) => !r.promise).map((r) => ({
|
|
506
|
+
name: r.name,
|
|
507
|
+
entry: command === "serve" ? r.devEntry : r.prodEntry,
|
|
508
|
+
shareScope: r.shareScope,
|
|
509
|
+
timeout: r.timeout,
|
|
510
|
+
retries: r.retries,
|
|
511
|
+
fallback: r.fallback,
|
|
512
|
+
breaker: r.breaker,
|
|
513
|
+
manifestUrl: manifestUrlFor(r, command)
|
|
514
|
+
}));
|
|
515
|
+
if (remotesJson.length === 0) return [];
|
|
516
|
+
return [
|
|
517
|
+
`registerRemotes(${JSON.stringify(remotesJson, jsonReplacer).replace(/"manifestUrl":null,?/g, "")});`
|
|
518
|
+
];
|
|
457
519
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
520
|
+
function genRuntimeProxyModule() {
|
|
521
|
+
const promiseApis = [
|
|
522
|
+
"loadRemote",
|
|
523
|
+
"loadShare",
|
|
524
|
+
"preloadRemote",
|
|
525
|
+
"getContainer",
|
|
526
|
+
"registerRemote",
|
|
527
|
+
"registerRemotes",
|
|
528
|
+
"registerShare",
|
|
529
|
+
"initSharing",
|
|
530
|
+
"registerPlugins",
|
|
531
|
+
"parseSpec"
|
|
532
|
+
];
|
|
533
|
+
const lines = [
|
|
534
|
+
`let __fulgurjs_mod_p;`,
|
|
535
|
+
`const __fulgurjs_rt = async () => {`,
|
|
536
|
+
` __fulgurjs_mod_p ??= import('virtual:fulgurjs-runtime');`,
|
|
537
|
+
` return await __fulgurjs_mod_p;`,
|
|
538
|
+
`};`,
|
|
539
|
+
...promiseApis.map((m) => `export const ${m} = (...a) => __fulgurjs_rt().then((m2) => m2.${m}(...a));`),
|
|
540
|
+
`export const getRuntime = () => (globalThis).__FULGURJS_RUNTIME__;`,
|
|
541
|
+
`export const getFulgurjsAppConfig = () =>`,
|
|
542
|
+
` (globalThis).__FULGURJS_RUNTIME__?.getFulgurjsAppConfig?.() ?? (globalThis).__FULGURJS_APP_CONFIG__ ?? {};`,
|
|
543
|
+
`export const provideFulgurjsAppConfig = (c) => {`,
|
|
544
|
+
` const g = (globalThis);`,
|
|
545
|
+
` g.__FULGURJS_APP_CONFIG__ = { ...(g.__FULGURJS_APP_CONFIG__ ?? {}), ...c };`,
|
|
546
|
+
` g.__FULGURJS_RUNTIME__?.provideFulgurjsAppConfig?.(c);`,
|
|
547
|
+
`};`,
|
|
548
|
+
`export const unwrapDefault = (ns) =>`,
|
|
549
|
+
` ns && typeof ns === 'object' && 'default' in ns ? (ns.default !== undefined ? ns.default : ns) : ns;`,
|
|
550
|
+
`export const version = (globalThis).__FULGURJS_RUNTIME__?.version;`,
|
|
551
|
+
`export default { get runtime() { return (globalThis).__FULGURJS_RUNTIME__; } };`,
|
|
552
|
+
``
|
|
553
|
+
];
|
|
554
|
+
return lines.join("\n");
|
|
466
555
|
}
|
|
467
|
-
function
|
|
468
|
-
|
|
556
|
+
function genDevRemoteEntry(options, base) {
|
|
557
|
+
const b = base.endsWith("/") ? base : `${base}/`;
|
|
558
|
+
const remoteLines = registerRemotesLines(options, "serve");
|
|
559
|
+
return `import ${JSON.stringify(`${b}@vite/client`)};
|
|
560
|
+
import { name as _fulgurjs_name, exposes, provides } from ${JSON.stringify(`${b}@id/__x00__virtual:fulgurjs-provides`)};
|
|
561
|
+
${remoteLines.length > 0 ? `import { registerRemotes } from ${JSON.stringify(`${b}@id/virtual:fulgurjs-runtime`)};
|
|
562
|
+
${remoteLines.join("\n")}` : ""}
|
|
563
|
+
|
|
564
|
+
export const name = _fulgurjs_name;
|
|
565
|
+
|
|
566
|
+
export async function init(shareScopeMap) {
|
|
567
|
+
for (const p of provides) {
|
|
568
|
+
const scope = shareScopeMap[p.shareScope] || (shareScopeMap[p.shareScope] = {});
|
|
569
|
+
const byName = scope[p.name] || (scope[p.name] = {});
|
|
570
|
+
if (byName[p.version]) continue; // \u5DF2\u6CE8\u518C\u7248\u672C\u6C38\u4E0D\u66FF\u6362
|
|
571
|
+
byName[p.version] = { version: p.version, get: p.get, from: name, eager: p.eager, loaded: false };
|
|
572
|
+
}
|
|
469
573
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
const
|
|
475
|
-
|
|
574
|
+
|
|
575
|
+
export async function get(moduleName) {
|
|
576
|
+
const loader = exposes[moduleName];
|
|
577
|
+
if (!loader) {
|
|
578
|
+
const err = new Error('MFU-006: module "' + moduleName + '" is not exposed by remote "' + name + '"');
|
|
579
|
+
err.code = 'MFU-006';
|
|
580
|
+
throw err;
|
|
476
581
|
}
|
|
477
|
-
return
|
|
582
|
+
return loader();
|
|
478
583
|
}
|
|
479
|
-
|
|
480
|
-
const canonical = canonicalBindings(bindings);
|
|
481
|
-
const sig = canonical.length ? `?f=${shortSig("shared", item.shareKey, canonical)}` : "";
|
|
482
|
-
return `${SHARED_FACADE_PREFIX}${item.shareKey}${sig}`;
|
|
584
|
+
`;
|
|
483
585
|
}
|
|
484
|
-
function
|
|
586
|
+
function genDevProvides(options) {
|
|
587
|
+
const exposes = [];
|
|
588
|
+
for (const e of options.exposes) {
|
|
589
|
+
const devUrl = `/${e.import.replace(/^\.?\//, "")}`;
|
|
590
|
+
exposes.push(
|
|
591
|
+
` ${JSON.stringify(e.name)}: () => import(${JSON.stringify(devUrl)}),`
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
const provides = providesRecords(options).map(
|
|
595
|
+
(p) => ` { shareScope: ${JSON.stringify(p.shareScope)}, name: ${JSON.stringify(p.name)}, version: ${JSON.stringify(p.version)}, eager: ${p.eager}, get: () => import("virtual:fulgurjs-shared:${p.name}") },`
|
|
596
|
+
);
|
|
597
|
+
return [
|
|
598
|
+
`export const name = ${JSON.stringify(options.name)};`,
|
|
599
|
+
`export const exposes = {`,
|
|
600
|
+
...exposes,
|
|
601
|
+
`};`,
|
|
602
|
+
`export const provides = [`,
|
|
603
|
+
...provides,
|
|
604
|
+
`];`,
|
|
605
|
+
""
|
|
606
|
+
].join("\n");
|
|
607
|
+
}
|
|
608
|
+
function genBuildRemoteEntry(options, exposeAbsPaths) {
|
|
609
|
+
const exposes = [];
|
|
610
|
+
for (const e of options.exposes) {
|
|
611
|
+
const abs = exposeAbsPaths[e.import];
|
|
612
|
+
if (!abs) continue;
|
|
613
|
+
exposes.push(` ${JSON.stringify(e.name)}: () => import(${JSON.stringify(abs)}),`);
|
|
614
|
+
}
|
|
615
|
+
const provides = providesRecords(options).map(
|
|
616
|
+
(p) => ` { shareScope: ${JSON.stringify(p.shareScope)}, name: ${JSON.stringify(p.name)}, version: ${JSON.stringify(p.version)}, eager: ${p.eager}, get: () => import("virtual:fulgurjs-shared:${p.name}") },`
|
|
617
|
+
);
|
|
618
|
+
const remoteLines = registerRemotesLines(options, "build");
|
|
619
|
+
return [
|
|
620
|
+
...remoteLines.length > 0 ? [`import { registerRemotes } from "virtual:fulgurjs-runtime";`, ...remoteLines] : [],
|
|
621
|
+
`const exposes = {`,
|
|
622
|
+
...exposes,
|
|
623
|
+
`};`,
|
|
624
|
+
`const provides = [`,
|
|
625
|
+
...provides,
|
|
626
|
+
`];`,
|
|
627
|
+
`export const name = ${JSON.stringify(options.name)};`,
|
|
628
|
+
``,
|
|
629
|
+
`export async function init(shareScopeMap) {`,
|
|
630
|
+
` for (const p of provides) {`,
|
|
631
|
+
` const scope = shareScopeMap[p.shareScope] || (shareScopeMap[p.shareScope] = {});`,
|
|
632
|
+
` const byName = scope[p.name] || (scope[p.name] = {});`,
|
|
633
|
+
` if (byName[p.version]) continue; // \u5DF2\u6CE8\u518C\u7248\u672C\u6C38\u4E0D\u66FF\u6362`,
|
|
634
|
+
` byName[p.version] = { version: p.version, get: p.get, from: name, eager: p.eager, loaded: false };`,
|
|
635
|
+
` }`,
|
|
636
|
+
`}`,
|
|
637
|
+
``,
|
|
638
|
+
`export async function get(moduleName) {`,
|
|
639
|
+
` const loader = exposes[moduleName];`,
|
|
640
|
+
` if (!loader) {`,
|
|
641
|
+
` const err = new Error('MFU-006: module "' + moduleName + '" is not exposed by remote "' + name + '"');`,
|
|
642
|
+
` err.code = 'MFU-006';`,
|
|
643
|
+
` throw err;`,
|
|
644
|
+
` }`,
|
|
645
|
+
` return loader();`,
|
|
646
|
+
`}`,
|
|
647
|
+
""
|
|
648
|
+
].join("\n");
|
|
649
|
+
}
|
|
650
|
+
function genDevManifest(options, base) {
|
|
651
|
+
const b = base.endsWith("/") ? base : `${base}/`;
|
|
652
|
+
return {
|
|
653
|
+
id: options.name,
|
|
654
|
+
name: options.name,
|
|
655
|
+
version: options.pkgDependencies?.["fulgurjs"] ?? "0.0.0",
|
|
656
|
+
devServer: true,
|
|
657
|
+
base: b,
|
|
658
|
+
entry: `${b}@fulgurjs-entry.js`,
|
|
659
|
+
/** 本地联调时供宿主端 dts 类型直连(见 dts.ts);远程不在本机时宿主回退 any 桩 */
|
|
660
|
+
fsRoot: options.root,
|
|
661
|
+
exposes: options.exposes.map((e) => ({
|
|
662
|
+
name: e.name,
|
|
663
|
+
src: e.import,
|
|
664
|
+
file: `${b}@fulgurjs-src/${e.import.replace(/^\.?\//, "")}`
|
|
665
|
+
})),
|
|
666
|
+
shared: options.shared.map((s) => ({
|
|
667
|
+
name: s.shareKey,
|
|
668
|
+
version: s.version,
|
|
669
|
+
singleton: s.singleton,
|
|
670
|
+
requiredVersion: s.requiredVersion,
|
|
671
|
+
shareScope: s.shareScope,
|
|
672
|
+
eager: s.eager
|
|
673
|
+
}))
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
function genProdManifest(options, exposeFiles, entryFile) {
|
|
677
|
+
return {
|
|
678
|
+
id: options.name,
|
|
679
|
+
name: options.name,
|
|
680
|
+
entry: entryFile,
|
|
681
|
+
exposes: exposeFiles,
|
|
682
|
+
shared: options.shared.map((s) => ({
|
|
683
|
+
name: s.shareKey,
|
|
684
|
+
version: s.version,
|
|
685
|
+
singleton: s.singleton,
|
|
686
|
+
requiredVersion: s.requiredVersion,
|
|
687
|
+
shareScope: s.shareScope,
|
|
688
|
+
eager: s.eager
|
|
689
|
+
})),
|
|
690
|
+
buildInfo: {
|
|
691
|
+
builtBy: "fulgurjs-federation",
|
|
692
|
+
timestamp: Date.now()
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// src/transform.ts
|
|
698
|
+
var lexerReady = null;
|
|
699
|
+
function ensureLexer() {
|
|
700
|
+
lexerReady ??= initLexer;
|
|
701
|
+
return lexerReady;
|
|
702
|
+
}
|
|
703
|
+
function isExposeTargetFile(cleanPath, root, exposes) {
|
|
704
|
+
for (const e of exposes) {
|
|
705
|
+
const abs = path2.resolve(root, e.import.replace(/^\.\//, ""));
|
|
706
|
+
if (cleanPath === abs) return true;
|
|
707
|
+
for (const ext of [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".vue"]) {
|
|
708
|
+
if (cleanPath === abs + ext) return true;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
function buildSharedMatcher(shared) {
|
|
714
|
+
const exact = /* @__PURE__ */ new Map();
|
|
715
|
+
const prefixes = [];
|
|
716
|
+
for (const s of shared) {
|
|
717
|
+
for (const alias of s.aliases) {
|
|
718
|
+
if (!exact.has(alias)) exact.set(alias, s);
|
|
719
|
+
}
|
|
720
|
+
if (s.configKey.endsWith("/")) prefixes.push({ prefix: s.configKey, item: s });
|
|
721
|
+
}
|
|
722
|
+
return { exact, prefixes };
|
|
723
|
+
}
|
|
724
|
+
function matchShared(spec, matcher) {
|
|
725
|
+
const exact = matcher.exact.get(spec);
|
|
726
|
+
if (exact) return exact;
|
|
727
|
+
for (const p of matcher.prefixes) {
|
|
728
|
+
if (spec.startsWith(p.prefix)) return p.item;
|
|
729
|
+
}
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
function serializeShareCallForFacade(item, fallbackUrl) {
|
|
733
|
+
const opts = [];
|
|
734
|
+
opts.push(`shareScope: ${JSON.stringify(item.shareScope)}`);
|
|
735
|
+
opts.push(`shareKey: ${JSON.stringify(item.shareKey)}`);
|
|
736
|
+
if (item.requiredVersion !== false) opts.push(`requiredVersion: ${JSON.stringify(item.requiredVersion)}`);
|
|
737
|
+
if (item.singleton) opts.push("singleton: true");
|
|
738
|
+
if (item.strictVersion) opts.push("strictVersion: true");
|
|
739
|
+
if (item.import !== false) {
|
|
740
|
+
const facadeUrl = fallbackUrl ?? SHARED_FACADE_PREFIX + item.shareKey;
|
|
741
|
+
opts.push(`fallback: () => import(${JSON.stringify(facadeUrl)})`);
|
|
742
|
+
}
|
|
743
|
+
return `__fulgurjs_loadShare(${JSON.stringify(item.shareKey)}, { ${opts.join(", ")} })`;
|
|
744
|
+
}
|
|
745
|
+
function serializeShareCall(item, devUrls) {
|
|
746
|
+
const opts = [];
|
|
747
|
+
opts.push(`shareScope: ${JSON.stringify(item.shareScope)}`);
|
|
748
|
+
opts.push(`shareKey: ${JSON.stringify(item.shareKey)}`);
|
|
749
|
+
if (item.requiredVersion !== false) opts.push(`requiredVersion: ${JSON.stringify(item.requiredVersion)}`);
|
|
750
|
+
if (item.singleton) opts.push("singleton: true");
|
|
751
|
+
if (item.strictVersion) opts.push("strictVersion: true");
|
|
752
|
+
if (item.import !== false) {
|
|
753
|
+
const facadeUrl = devUrls ? devUrls.namespaceFacade(item.shareKey) : SHARED_FACADE_PREFIX + item.shareKey;
|
|
754
|
+
opts.push(`fallback: () => import(${JSON.stringify(facadeUrl)})`);
|
|
755
|
+
}
|
|
756
|
+
return `__fulgurjs_loadShare(${JSON.stringify(item.shareKey)}, { ${opts.join(", ")} })`;
|
|
757
|
+
}
|
|
758
|
+
function stripComments(s) {
|
|
759
|
+
return s.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
|
|
760
|
+
}
|
|
761
|
+
function parseBindings(inner) {
|
|
762
|
+
const out = [];
|
|
763
|
+
for (const piece of stripComments(inner).split(",")) {
|
|
764
|
+
const raw = piece.trim();
|
|
765
|
+
if (!raw) continue;
|
|
766
|
+
if (/^type\s/.test(raw)) continue;
|
|
767
|
+
const asMatch = raw.match(/^(.*?)\s+as\s+(.+)$/);
|
|
768
|
+
const imported = asMatch ? asMatch[1].trim() : raw;
|
|
769
|
+
const local = asMatch ? asMatch[2].trim() : raw;
|
|
770
|
+
out.push({ imported, local, isDefault: imported === "default" });
|
|
771
|
+
}
|
|
772
|
+
return out;
|
|
773
|
+
}
|
|
774
|
+
function parseImportClause(clause) {
|
|
775
|
+
const nsMatch = clause.match(/\*\s+as\s+(\w+)/);
|
|
776
|
+
const braceStart = clause.indexOf("{");
|
|
777
|
+
const bindings = braceStart !== -1 ? parseBindings(clause.slice(braceStart + 1, clause.lastIndexOf("}"))) : null;
|
|
778
|
+
let head = clause.replace(/^\s*import\s*/, "");
|
|
779
|
+
if (braceStart !== -1) head = head.slice(0, head.indexOf("{"));
|
|
780
|
+
if (nsMatch) head = head.slice(0, head.indexOf("*"));
|
|
781
|
+
const defaultLocal = head.replace(/,\s*$/, "").trim() || null;
|
|
782
|
+
return { ns: nsMatch?.[1] ?? null, bindings, defaultLocal };
|
|
783
|
+
}
|
|
784
|
+
var JS_EXT_RE = /\.(m|c)?[jt]sx?$/;
|
|
785
|
+
function isTransformableId(id, allowNodeModules = false) {
|
|
786
|
+
const clean = id.split("?")[0];
|
|
787
|
+
if (!JS_EXT_RE.test(clean) && !clean.endsWith(".vue")) return false;
|
|
788
|
+
if (clean.includes("node_modules") && !allowNodeModules) return false;
|
|
789
|
+
return true;
|
|
790
|
+
}
|
|
791
|
+
function isPluginProcessedModule(code) {
|
|
792
|
+
return code.includes("virtual:fulgurjs-runtime-proxy") || code.includes("__fulgurjs_loadRemote") || code.includes("__fulgurjs_loadShare") || code.includes(INIT_MODULE_MARKER);
|
|
793
|
+
}
|
|
794
|
+
var facadeRegistry = /* @__PURE__ */ new Map();
|
|
795
|
+
function shortSig(kind, key, bindings) {
|
|
796
|
+
const full = kind + "|" + key + "|" + bindings.join("|");
|
|
797
|
+
let h = 5381;
|
|
798
|
+
for (let i = 0; i < full.length; i++) h = (h << 5) + h + full.charCodeAt(i) | 0;
|
|
799
|
+
const id = (h >>> 0).toString(36) + bindings.length.toString(36);
|
|
800
|
+
facadeRegistry.set(id, kind === "shared" ? { bindings, shareKey: key } : { bindings, remoteName: key });
|
|
801
|
+
return id;
|
|
802
|
+
}
|
|
803
|
+
function getFacadeEntry(id) {
|
|
804
|
+
return facadeRegistry.get(id);
|
|
805
|
+
}
|
|
806
|
+
function canonicalBindings(bindings) {
|
|
807
|
+
const names = /* @__PURE__ */ new Set();
|
|
808
|
+
for (const bRaw of bindings) {
|
|
809
|
+
if (bRaw === "default") continue;
|
|
810
|
+
const asMatch = bRaw.match(/^(.*?)\s+as\s+(.+)$/);
|
|
811
|
+
names.add((asMatch ? asMatch[1] : bRaw).trim());
|
|
812
|
+
}
|
|
813
|
+
return [...names].sort();
|
|
814
|
+
}
|
|
815
|
+
function bindingFacadeId(item, bindings) {
|
|
816
|
+
const canonical = canonicalBindings(bindings);
|
|
817
|
+
const sig = canonical.length ? `?f=${shortSig("shared", item.shareKey, canonical)}` : "";
|
|
818
|
+
return `${SHARED_FACADE_PREFIX}${item.shareKey}${sig}`;
|
|
819
|
+
}
|
|
820
|
+
function facadeSpecFor(ctx, item, bindings) {
|
|
485
821
|
const id = bindingFacadeId(item, bindings);
|
|
486
822
|
return ctx.devUrls ? ctx.devUrls.bindingFacade(id) : id;
|
|
487
823
|
}
|
|
@@ -511,7 +847,7 @@ async function transformModule(code, id, ctx) {
|
|
|
511
847
|
for (const [alias, item] of sharedByAlias) {
|
|
512
848
|
const re = new RegExp(`require\\((["'])${alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\1\\)`, "g");
|
|
513
849
|
if (!re.test(code)) continue;
|
|
514
|
-
code = code.replace(re, `require(${JSON.stringify(`virtual:
|
|
850
|
+
code = code.replace(re, `require(${JSON.stringify(`virtual:fulgurjs-cjs-ns:${item.shareKey}`)})`);
|
|
515
851
|
cjsEdited = true;
|
|
516
852
|
}
|
|
517
853
|
if (!cjsEdited) return null;
|
|
@@ -532,7 +868,7 @@ async function transformModule(code, id, ctx) {
|
|
|
532
868
|
let usesRuntimeHelpers = false;
|
|
533
869
|
const tlaLines = [];
|
|
534
870
|
let tempIdx = 0;
|
|
535
|
-
const genTemp = () => `
|
|
871
|
+
const genTemp = () => `__fulgurjs_m${tempIdx++}`;
|
|
536
872
|
const remap = (spec) => ctx.remapSpecifier?.(spec) ?? spec;
|
|
537
873
|
const remoteExposeName = (spec, remoteKey) => {
|
|
538
874
|
if (!spec.startsWith(`${remoteKey}/`)) return null;
|
|
@@ -546,7 +882,7 @@ async function transformModule(code, id, ctx) {
|
|
|
546
882
|
];
|
|
547
883
|
const genTlaOverwrite = (stmtStart, stmtEnd, shared, remoteName, exposeName, clauseRaw, clause) => {
|
|
548
884
|
usesRuntimeHelpers = true;
|
|
549
|
-
const call = shared ? serializeShareCall(shared, ctx?.devUrls) : `
|
|
885
|
+
const call = shared ? serializeShareCall(shared, ctx?.devUrls) : `__fulgurjs_loadRemote(${JSON.stringify(`${remoteName}/${exposeName}`)})`;
|
|
550
886
|
const nsAs = clauseRaw.match(/export\s+\*\s+as\s+(\w+)\s+from/);
|
|
551
887
|
if (nsAs) {
|
|
552
888
|
s.overwrite(stmtStart, stmtEnd, `const ${nsAs[1]} = await ${call};
|
|
@@ -560,14 +896,14 @@ export { ${nsAs[1]} };`);
|
|
|
560
896
|
const tmp = genTemp();
|
|
561
897
|
const parts = [`${tmp} = await ${call}`];
|
|
562
898
|
if (clause.ns) parts.push(`${clause.ns} = ${tmp}`);
|
|
563
|
-
if (clause.defaultLocal) parts.push(`${clause.defaultLocal} =
|
|
899
|
+
if (clause.defaultLocal) parts.push(`${clause.defaultLocal} = __fulgurjsU(${tmp})`);
|
|
564
900
|
const named = clause.bindings?.filter((b) => !b.isDefault) ?? [];
|
|
565
901
|
if (named.length) {
|
|
566
902
|
const destructure = named.map((b) => b.imported === b.local ? b.local : `${b.imported}: ${b.local}`);
|
|
567
903
|
parts.push(`{ ${destructure.join(", ")} } = ${tmp}`);
|
|
568
904
|
}
|
|
569
905
|
for (const b of clause.bindings?.filter((x) => x.isDefault) ?? []) {
|
|
570
|
-
parts.push(`${b.local} =
|
|
906
|
+
parts.push(`${b.local} = __fulgurjsU(${tmp})`);
|
|
571
907
|
}
|
|
572
908
|
s.overwrite(stmtStart, stmtEnd, `const ${parts.join(", ")}`);
|
|
573
909
|
};
|
|
@@ -599,7 +935,7 @@ export { ${nsAs[1]} };`);
|
|
|
599
935
|
const inner = clauseRaw.slice(clauseRaw.indexOf("{") + 1, clauseRaw.lastIndexOf("}"));
|
|
600
936
|
if (/export\s+\*/.test(clauseRaw) && !clauseRaw.includes("{")) {
|
|
601
937
|
throw new Error(
|
|
602
|
-
`[
|
|
938
|
+
`[fulgurjs] "export * from '${spec2}'" on a shared module is not supported (ESM cannot create dynamic export bindings). Use named re-exports: "export { a, b } from '${spec2}'".`
|
|
603
939
|
);
|
|
604
940
|
}
|
|
605
941
|
const bindings = parseBindings(inner).map((b) => b.imported === "default" ? "default" : b.imported);
|
|
@@ -630,351 +966,21 @@ export { ${nsAs[1]} };`);
|
|
|
630
966
|
s.overwrite(
|
|
631
967
|
callStart,
|
|
632
968
|
closeParen + 1,
|
|
633
|
-
`
|
|
969
|
+
`__fulgurjs_loadRemote(${JSON.stringify(`${remote.name}/${exposeName}`)})`
|
|
634
970
|
);
|
|
635
971
|
}
|
|
636
972
|
}
|
|
637
973
|
if (!edited) return null;
|
|
638
974
|
if (usesRuntimeHelpers) {
|
|
639
|
-
const runtimeSpec = JSON.stringify(ctx.devUrls?.runtime ?? "virtual:
|
|
975
|
+
const runtimeSpec = JSON.stringify(ctx.devUrls?.runtime ?? "virtual:fulgurjs-runtime");
|
|
640
976
|
s.prepend(
|
|
641
|
-
`import { loadShare as
|
|
977
|
+
`import { loadShare as __fulgurjs_loadShare, loadRemote as __fulgurjs_loadRemote, unwrapDefault as __fulgurjsU } from ${runtimeSpec};
|
|
642
978
|
`
|
|
643
979
|
);
|
|
644
980
|
}
|
|
645
981
|
return { code: s.toString(), map: null };
|
|
646
982
|
}
|
|
647
983
|
|
|
648
|
-
// src/virtual.ts
|
|
649
|
-
function jsonReplacer(_k, v) {
|
|
650
|
-
return v;
|
|
651
|
-
}
|
|
652
|
-
function genSharedFacade(specifier, exportNames) {
|
|
653
|
-
const names = (exportNames ?? []).filter(
|
|
654
|
-
(n) => n !== "default" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(n)
|
|
655
|
-
);
|
|
656
|
-
if (names.length === 0) {
|
|
657
|
-
return [
|
|
658
|
-
`import * as __fulgur_facade from ${JSON.stringify(specifier)};`,
|
|
659
|
-
`export * from ${JSON.stringify(specifier)};`,
|
|
660
|
-
`export default __fulgur_facade.default ?? __fulgur_facade;`,
|
|
661
|
-
""
|
|
662
|
-
].join("\n");
|
|
663
|
-
}
|
|
664
|
-
return [
|
|
665
|
-
`import * as __fulgur_facade from ${JSON.stringify(specifier)};`,
|
|
666
|
-
...names.map((n) => `export const ${n} = __fulgur_facade[${JSON.stringify(n)}];`),
|
|
667
|
-
`export default __fulgur_facade.default ?? __fulgur_facade;`,
|
|
668
|
-
""
|
|
669
|
-
].join("\n");
|
|
670
|
-
}
|
|
671
|
-
function genSharedNsFacade(item, loadShareCall, exportNames) {
|
|
672
|
-
const lines = [
|
|
673
|
-
`import { loadShare as __fulgur_loadShare, unwrapDefault as __fulgurU } from "virtual:fulgur-runtime";`,
|
|
674
|
-
`const __fulgur_m = await ${loadShareCall};`,
|
|
675
|
-
`const __fulgur_d = __fulgurU(__fulgur_m);`,
|
|
676
|
-
`export default __fulgur_d;`
|
|
677
|
-
];
|
|
678
|
-
const seen = /* @__PURE__ */ new Set(["default"]);
|
|
679
|
-
for (const name of exportNames) {
|
|
680
|
-
if (seen.has(name) || !/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) continue;
|
|
681
|
-
seen.add(name);
|
|
682
|
-
lines.push(`export const ${name} = __fulgur_d[${JSON.stringify(name)}];`);
|
|
683
|
-
}
|
|
684
|
-
lines.push("");
|
|
685
|
-
return lines.join("\n");
|
|
686
|
-
}
|
|
687
|
-
function genBindingFacade(item, bindings, loadShareCall) {
|
|
688
|
-
const lines = [
|
|
689
|
-
`import { loadShare as __fulgur_loadShare, unwrapDefault as __fulgurU } from "virtual:fulgur-runtime";`,
|
|
690
|
-
`const __fulgur_m = await ${loadShareCall};`
|
|
691
|
-
];
|
|
692
|
-
const seen = /* @__PURE__ */ new Set();
|
|
693
|
-
for (const bRaw of bindings) {
|
|
694
|
-
if (bRaw === "default") continue;
|
|
695
|
-
const asMatch = bRaw.match(/^(.*?)\s+as\s+(.+)$/);
|
|
696
|
-
const imported = (asMatch ? asMatch[1] : bRaw).trim();
|
|
697
|
-
if (seen.has(imported)) continue;
|
|
698
|
-
seen.add(imported);
|
|
699
|
-
lines.push(`export const ${imported} = __fulgur_m.${imported};`);
|
|
700
|
-
}
|
|
701
|
-
lines.push(`export default __fulgurU(__fulgur_m);`);
|
|
702
|
-
lines.push("");
|
|
703
|
-
return lines.join("\n");
|
|
704
|
-
}
|
|
705
|
-
function genRemoteBindingFacade(remoteSpec, bindings) {
|
|
706
|
-
const lines = [
|
|
707
|
-
`import { loadRemote as __fulgur_loadRemote, unwrapDefault as __fulgurU } from "virtual:fulgur-runtime";`,
|
|
708
|
-
`const __fulgur_m = await __fulgur_loadRemote(${JSON.stringify(remoteSpec)});`
|
|
709
|
-
];
|
|
710
|
-
const seen = /* @__PURE__ */ new Set();
|
|
711
|
-
for (const bRaw of bindings) {
|
|
712
|
-
if (bRaw === "default") continue;
|
|
713
|
-
const asMatch = bRaw.match(/^(.*?)\s+as\s+(.+)$/);
|
|
714
|
-
const imported = (asMatch ? asMatch[1] : bRaw).trim();
|
|
715
|
-
if (seen.has(imported)) continue;
|
|
716
|
-
seen.add(imported);
|
|
717
|
-
lines.push(`export const ${imported} = __fulgur_m.${imported};`);
|
|
718
|
-
}
|
|
719
|
-
lines.push(`export default __fulgurU(__fulgur_m);`);
|
|
720
|
-
lines.push("");
|
|
721
|
-
return lines.join("\n");
|
|
722
|
-
}
|
|
723
|
-
function providesRecords(options) {
|
|
724
|
-
return options.shared.filter((s) => s.import !== false).map((s) => ({
|
|
725
|
-
shareScope: s.shareScope,
|
|
726
|
-
name: s.shareKey,
|
|
727
|
-
version: s.version,
|
|
728
|
-
eager: s.eager,
|
|
729
|
-
from: options.name
|
|
730
|
-
}));
|
|
731
|
-
}
|
|
732
|
-
function genInitModule(options, command) {
|
|
733
|
-
const lines = [];
|
|
734
|
-
lines.push(`import { initSharing, registerShare, registerRemotes, registerPlugins } from "virtual:fulgur-runtime";`);
|
|
735
|
-
const provides = providesRecords(options);
|
|
736
|
-
const eagerShared = options.shared.filter((s) => s.eager && s.import !== false);
|
|
737
|
-
eagerShared.forEach((s, i) => {
|
|
738
|
-
lines.push(`import * as __fulgur_eager_${i} from "virtual:fulgur-shared:${s.shareKey}";`);
|
|
739
|
-
});
|
|
740
|
-
const isDevHost = command === "serve" && options.remotes.length > 0;
|
|
741
|
-
const loadedFlag = isDevHost ? "true" : "false";
|
|
742
|
-
lines.push(`initSharing(${JSON.stringify(options.shareScope)});`);
|
|
743
|
-
if (options.runtimePlugins.length > 0) {
|
|
744
|
-
options.runtimePlugins.forEach((p, i) => {
|
|
745
|
-
lines.push(`import * as __fulgur_rp_${i} from ${JSON.stringify(p)};`);
|
|
746
|
-
});
|
|
747
|
-
lines.push(
|
|
748
|
-
`registerPlugins([${options.runtimePlugins.map((_, i) => `(__fulgur_rp_${i}.default ?? __fulgur_rp_${i})`).join(", ")}]);`
|
|
749
|
-
);
|
|
750
|
-
}
|
|
751
|
-
if (options.remotes.length > 0) {
|
|
752
|
-
lines.push(...registerRemotesLines(options, command));
|
|
753
|
-
}
|
|
754
|
-
provides.forEach((p) => {
|
|
755
|
-
const eagerIdx = eagerShared.findIndex((s) => s.shareKey === p.name && s.shareScope === p.shareScope);
|
|
756
|
-
if (p.eager && eagerIdx !== -1) {
|
|
757
|
-
lines.push(
|
|
758
|
-
`registerShare(${JSON.stringify(p.shareScope)}, ${JSON.stringify(p.name)}, ${JSON.stringify(p.version)}, () => Promise.resolve(__fulgur_eager_${eagerIdx}), { from: ${JSON.stringify(p.from)}, eager: true, loaded: ${loadedFlag} });`
|
|
759
|
-
);
|
|
760
|
-
} else {
|
|
761
|
-
lines.push(
|
|
762
|
-
`registerShare(${JSON.stringify(p.shareScope)}, ${JSON.stringify(p.name)}, ${JSON.stringify(p.version)}, () => import("virtual:fulgur-shared:${p.name}"), { from: ${JSON.stringify(p.from)}, eager: false, loaded: ${loadedFlag} });`
|
|
763
|
-
);
|
|
764
|
-
}
|
|
765
|
-
});
|
|
766
|
-
return `${lines.join("\n")}
|
|
767
|
-
`;
|
|
768
|
-
}
|
|
769
|
-
function manifestUrlFor(r, command) {
|
|
770
|
-
const entry = command === "serve" ? r.devEntry : r.prodEntry;
|
|
771
|
-
if (!entry) return null;
|
|
772
|
-
try {
|
|
773
|
-
const u = new URL(entry);
|
|
774
|
-
if (u.pathname.includes("@fulgur-entry.js")) {
|
|
775
|
-
u.pathname = u.pathname.replace("@fulgur-entry.js", "@fulgur-manifest.json");
|
|
776
|
-
} else {
|
|
777
|
-
u.pathname = u.pathname.replace(/[^/]*$/, "") + "fulgur-manifest.json";
|
|
778
|
-
}
|
|
779
|
-
return u.href;
|
|
780
|
-
} catch {
|
|
781
|
-
return null;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
function registerRemotesLines(options, command) {
|
|
785
|
-
if (options.remotes.length === 0) return [];
|
|
786
|
-
const remotesJson = options.remotes.filter((r) => !r.promise).map((r) => ({
|
|
787
|
-
name: r.name,
|
|
788
|
-
entry: command === "serve" ? r.devEntry : r.prodEntry,
|
|
789
|
-
shareScope: r.shareScope,
|
|
790
|
-
timeout: r.timeout,
|
|
791
|
-
retries: r.retries,
|
|
792
|
-
fallback: r.fallback,
|
|
793
|
-
breaker: r.breaker,
|
|
794
|
-
manifestUrl: manifestUrlFor(r, command)
|
|
795
|
-
}));
|
|
796
|
-
if (remotesJson.length === 0) return [];
|
|
797
|
-
return [
|
|
798
|
-
`registerRemotes(${JSON.stringify(remotesJson, jsonReplacer).replace(/"manifestUrl":null,?/g, "")});`
|
|
799
|
-
];
|
|
800
|
-
}
|
|
801
|
-
function genRuntimeProxyModule() {
|
|
802
|
-
const promiseApis = [
|
|
803
|
-
"loadRemote",
|
|
804
|
-
"loadShare",
|
|
805
|
-
"preloadRemote",
|
|
806
|
-
"getContainer",
|
|
807
|
-
"registerRemote",
|
|
808
|
-
"registerRemotes",
|
|
809
|
-
"registerShare",
|
|
810
|
-
"initSharing",
|
|
811
|
-
"registerPlugins",
|
|
812
|
-
"parseSpec"
|
|
813
|
-
];
|
|
814
|
-
const lines = [
|
|
815
|
-
`let __fulgur_mod_p;`,
|
|
816
|
-
`const __fulgur_rt = async () => {`,
|
|
817
|
-
` __fulgur_mod_p ??= import('virtual:fulgur-runtime');`,
|
|
818
|
-
` return await __fulgur_mod_p;`,
|
|
819
|
-
`};`,
|
|
820
|
-
...promiseApis.map((m) => `export const ${m} = (...a) => __fulgur_rt().then((m2) => m2.${m}(...a));`),
|
|
821
|
-
`export const getRuntime = () => (globalThis).__FULGUR_RUNTIME__;`,
|
|
822
|
-
`export const getFulgurAppConfig = () =>`,
|
|
823
|
-
` (globalThis).__FULGUR_RUNTIME__?.getFulgurAppConfig?.() ?? (globalThis).__FULGUR_APP_CONFIG__ ?? {};`,
|
|
824
|
-
`export const provideFulgurAppConfig = (c) => {`,
|
|
825
|
-
` const g = (globalThis);`,
|
|
826
|
-
` g.__FULGUR_APP_CONFIG__ = { ...(g.__FULGUR_APP_CONFIG__ ?? {}), ...c };`,
|
|
827
|
-
` g.__FULGUR_RUNTIME__?.provideFulgurAppConfig?.(c);`,
|
|
828
|
-
`};`,
|
|
829
|
-
`export const unwrapDefault = (ns) =>`,
|
|
830
|
-
` ns && typeof ns === 'object' && 'default' in ns ? (ns.default !== undefined ? ns.default : ns) : ns;`,
|
|
831
|
-
`export const version = (globalThis).__FULGUR_RUNTIME__?.version;`,
|
|
832
|
-
`export default { get runtime() { return (globalThis).__FULGUR_RUNTIME__; } };`,
|
|
833
|
-
``
|
|
834
|
-
];
|
|
835
|
-
return lines.join("\n");
|
|
836
|
-
}
|
|
837
|
-
function genDevRemoteEntry(options, base) {
|
|
838
|
-
const b = base.endsWith("/") ? base : `${base}/`;
|
|
839
|
-
const remoteLines = registerRemotesLines(options, "serve");
|
|
840
|
-
return `import ${JSON.stringify(`${b}@vite/client`)};
|
|
841
|
-
import { name as _fulgur_name, exposes, provides } from ${JSON.stringify(`${b}@id/__x00__virtual:fulgur-provides`)};
|
|
842
|
-
${remoteLines.length > 0 ? `import { registerRemotes } from ${JSON.stringify(`${b}@id/virtual:fulgur-runtime`)};
|
|
843
|
-
${remoteLines.join("\n")}` : ""}
|
|
844
|
-
|
|
845
|
-
export const name = _fulgur_name;
|
|
846
|
-
|
|
847
|
-
export async function init(shareScopeMap) {
|
|
848
|
-
for (const p of provides) {
|
|
849
|
-
const scope = shareScopeMap[p.shareScope] || (shareScopeMap[p.shareScope] = {});
|
|
850
|
-
const byName = scope[p.name] || (scope[p.name] = {});
|
|
851
|
-
if (byName[p.version]) continue; // \u5DF2\u6CE8\u518C\u7248\u672C\u6C38\u4E0D\u66FF\u6362
|
|
852
|
-
byName[p.version] = { version: p.version, get: p.get, from: name, eager: p.eager, loaded: false };
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
export async function get(moduleName) {
|
|
857
|
-
const loader = exposes[moduleName];
|
|
858
|
-
if (!loader) {
|
|
859
|
-
const err = new Error('MFU-006: module "' + moduleName + '" is not exposed by remote "' + name + '"');
|
|
860
|
-
err.code = 'MFU-006';
|
|
861
|
-
throw err;
|
|
862
|
-
}
|
|
863
|
-
return loader();
|
|
864
|
-
}
|
|
865
|
-
`;
|
|
866
|
-
}
|
|
867
|
-
function genDevProvides(options) {
|
|
868
|
-
const exposes = [];
|
|
869
|
-
for (const e of options.exposes) {
|
|
870
|
-
const devUrl = `/${e.import.replace(/^\.?\//, "")}`;
|
|
871
|
-
exposes.push(
|
|
872
|
-
` ${JSON.stringify(e.name)}: () => import(${JSON.stringify(devUrl)}),`
|
|
873
|
-
);
|
|
874
|
-
}
|
|
875
|
-
const provides = providesRecords(options).map(
|
|
876
|
-
(p) => ` { shareScope: ${JSON.stringify(p.shareScope)}, name: ${JSON.stringify(p.name)}, version: ${JSON.stringify(p.version)}, eager: ${p.eager}, get: () => import("virtual:fulgur-shared:${p.name}") },`
|
|
877
|
-
);
|
|
878
|
-
return [
|
|
879
|
-
`export const name = ${JSON.stringify(options.name)};`,
|
|
880
|
-
`export const exposes = {`,
|
|
881
|
-
...exposes,
|
|
882
|
-
`};`,
|
|
883
|
-
`export const provides = [`,
|
|
884
|
-
...provides,
|
|
885
|
-
`];`,
|
|
886
|
-
""
|
|
887
|
-
].join("\n");
|
|
888
|
-
}
|
|
889
|
-
function genBuildRemoteEntry(options, exposeAbsPaths) {
|
|
890
|
-
const exposes = [];
|
|
891
|
-
for (const e of options.exposes) {
|
|
892
|
-
const abs = exposeAbsPaths[e.import];
|
|
893
|
-
if (!abs) continue;
|
|
894
|
-
exposes.push(` ${JSON.stringify(e.name)}: () => import(${JSON.stringify(abs)}),`);
|
|
895
|
-
}
|
|
896
|
-
const provides = providesRecords(options).map(
|
|
897
|
-
(p) => ` { shareScope: ${JSON.stringify(p.shareScope)}, name: ${JSON.stringify(p.name)}, version: ${JSON.stringify(p.version)}, eager: ${p.eager}, get: () => import("virtual:fulgur-shared:${p.name}") },`
|
|
898
|
-
);
|
|
899
|
-
const remoteLines = registerRemotesLines(options, "build");
|
|
900
|
-
return [
|
|
901
|
-
...remoteLines.length > 0 ? [`import { registerRemotes } from "virtual:fulgur-runtime";`, ...remoteLines] : [],
|
|
902
|
-
`const exposes = {`,
|
|
903
|
-
...exposes,
|
|
904
|
-
`};`,
|
|
905
|
-
`const provides = [`,
|
|
906
|
-
...provides,
|
|
907
|
-
`];`,
|
|
908
|
-
`export const name = ${JSON.stringify(options.name)};`,
|
|
909
|
-
``,
|
|
910
|
-
`export async function init(shareScopeMap) {`,
|
|
911
|
-
` for (const p of provides) {`,
|
|
912
|
-
` const scope = shareScopeMap[p.shareScope] || (shareScopeMap[p.shareScope] = {});`,
|
|
913
|
-
` const byName = scope[p.name] || (scope[p.name] = {});`,
|
|
914
|
-
` if (byName[p.version]) continue; // \u5DF2\u6CE8\u518C\u7248\u672C\u6C38\u4E0D\u66FF\u6362`,
|
|
915
|
-
` byName[p.version] = { version: p.version, get: p.get, from: name, eager: p.eager, loaded: false };`,
|
|
916
|
-
` }`,
|
|
917
|
-
`}`,
|
|
918
|
-
``,
|
|
919
|
-
`export async function get(moduleName) {`,
|
|
920
|
-
` const loader = exposes[moduleName];`,
|
|
921
|
-
` if (!loader) {`,
|
|
922
|
-
` const err = new Error('MFU-006: module "' + moduleName + '" is not exposed by remote "' + name + '"');`,
|
|
923
|
-
` err.code = 'MFU-006';`,
|
|
924
|
-
` throw err;`,
|
|
925
|
-
` }`,
|
|
926
|
-
` return loader();`,
|
|
927
|
-
`}`,
|
|
928
|
-
""
|
|
929
|
-
].join("\n");
|
|
930
|
-
}
|
|
931
|
-
function genDevManifest(options, base) {
|
|
932
|
-
const b = base.endsWith("/") ? base : `${base}/`;
|
|
933
|
-
return {
|
|
934
|
-
id: options.name,
|
|
935
|
-
name: options.name,
|
|
936
|
-
version: options.pkgDependencies?.["fulgur"] ?? "0.0.0",
|
|
937
|
-
devServer: true,
|
|
938
|
-
base: b,
|
|
939
|
-
entry: `${b}@fulgur-entry.js`,
|
|
940
|
-
/** 本地联调时供宿主端 dts 类型直连(见 dts.ts);远程不在本机时宿主回退 any 桩 */
|
|
941
|
-
fsRoot: options.root,
|
|
942
|
-
exposes: options.exposes.map((e) => ({
|
|
943
|
-
name: e.name,
|
|
944
|
-
src: e.import,
|
|
945
|
-
file: `${b}@fulgur-src/${e.import.replace(/^\.?\//, "")}`
|
|
946
|
-
})),
|
|
947
|
-
shared: options.shared.map((s) => ({
|
|
948
|
-
name: s.shareKey,
|
|
949
|
-
version: s.version,
|
|
950
|
-
singleton: s.singleton,
|
|
951
|
-
requiredVersion: s.requiredVersion,
|
|
952
|
-
shareScope: s.shareScope,
|
|
953
|
-
eager: s.eager
|
|
954
|
-
}))
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
function genProdManifest(options, exposeFiles, entryFile) {
|
|
958
|
-
return {
|
|
959
|
-
id: options.name,
|
|
960
|
-
name: options.name,
|
|
961
|
-
entry: entryFile,
|
|
962
|
-
exposes: exposeFiles,
|
|
963
|
-
shared: options.shared.map((s) => ({
|
|
964
|
-
name: s.shareKey,
|
|
965
|
-
version: s.version,
|
|
966
|
-
singleton: s.singleton,
|
|
967
|
-
requiredVersion: s.requiredVersion,
|
|
968
|
-
shareScope: s.shareScope,
|
|
969
|
-
eager: s.eager
|
|
970
|
-
})),
|
|
971
|
-
buildInfo: {
|
|
972
|
-
builtBy: "fulgur-federation",
|
|
973
|
-
timestamp: Date.now()
|
|
974
|
-
}
|
|
975
|
-
};
|
|
976
|
-
}
|
|
977
|
-
|
|
978
984
|
// src/dts.ts
|
|
979
985
|
import fs2 from "fs";
|
|
980
986
|
import path3 from "path";
|
|
@@ -982,7 +988,7 @@ async function fetchManifest(devEntry, attempts = 30, delayMs = 2e3) {
|
|
|
982
988
|
let manifestUrl;
|
|
983
989
|
try {
|
|
984
990
|
const u = new URL(devEntry);
|
|
985
|
-
u.pathname = u.pathname.replace("@
|
|
991
|
+
u.pathname = u.pathname.replace("@fulgurjs-entry.js", "@fulgurjs-manifest.json");
|
|
986
992
|
manifestUrl = u;
|
|
987
993
|
} catch {
|
|
988
994
|
return null;
|
|
@@ -1008,7 +1014,7 @@ function sourceHasDefaultExport(file) {
|
|
|
1008
1014
|
async function generateDevTypes(options, _server) {
|
|
1009
1015
|
const dtsOpt = options.dts === void 0 ? true : options.dts;
|
|
1010
1016
|
if (dtsOpt === false) return;
|
|
1011
|
-
const defaultDir = fs2.existsSync(path3.join(options.root, "src")) ? "src/
|
|
1017
|
+
const defaultDir = fs2.existsSync(path3.join(options.root, "src")) ? "src/fulgurjs-types" : "fulgurjs-types";
|
|
1012
1018
|
const dir = typeof dtsOpt === "object" ? dtsOpt.dir ?? defaultDir : defaultDir;
|
|
1013
1019
|
const outDir = path3.join(options.root, dir);
|
|
1014
1020
|
fs2.mkdirSync(outDir, { recursive: true });
|
|
@@ -1016,18 +1022,18 @@ async function generateDevTypes(options, _server) {
|
|
|
1016
1022
|
if (!remote.devEntry || remote.promise) continue;
|
|
1017
1023
|
const manifest = await fetchManifest(remote.devEntry);
|
|
1018
1024
|
if (!manifest || !manifest.exposes) {
|
|
1019
|
-
console.warn(`[
|
|
1025
|
+
console.warn(`[fulgurjs] dts: remote "${remote.key}" dev manifest unavailable; type mapping skipped.`);
|
|
1020
1026
|
continue;
|
|
1021
1027
|
}
|
|
1022
1028
|
const remoteRoot = manifest.fsRoot;
|
|
1023
1029
|
if (!remoteRoot || !fs2.existsSync(remoteRoot)) {
|
|
1024
1030
|
console.warn(
|
|
1025
|
-
`[
|
|
1031
|
+
`[fulgurjs] dts: remote "${remote.key}" is not on this machine; type mapping skipped (module types fall back to any).`
|
|
1026
1032
|
);
|
|
1027
1033
|
continue;
|
|
1028
1034
|
}
|
|
1029
1035
|
const lines = [
|
|
1030
|
-
`// \u81EA\u52A8\u751F\u6210\
|
|
1036
|
+
`// \u81EA\u52A8\u751F\u6210\uFF1Afulgurjs-federation dev \u7C7B\u578B\u76F4\u8FDE\uFF08remote: ${remote.name}\uFF09`,
|
|
1031
1037
|
`// \u91CD\u65B0\u751F\u6210\uFF1A\u91CD\u542F host dev server`
|
|
1032
1038
|
];
|
|
1033
1039
|
for (const expose of manifest.exposes ?? []) {
|
|
@@ -1054,16 +1060,16 @@ async function generateDevTypes(options, _server) {
|
|
|
1054
1060
|
fs2.writeFileSync(path3.join(outDir, `${remote.key}.d.ts`), `${lines.join("\n")}
|
|
1055
1061
|
`);
|
|
1056
1062
|
console.log(
|
|
1057
|
-
`[
|
|
1063
|
+
`[fulgurjs] dts: generated ${dir}/${remote.key}.d.ts (${manifest.exposes?.length ?? 0} exposes). \u786E\u4FDD tsconfig include \u5305\u542B "${dir}" \u4EE5\u83B7\u5F97\u6E90\u7801\u7EA7\u7C7B\u578B\u8865\u5168\u3002`
|
|
1058
1064
|
);
|
|
1059
1065
|
}
|
|
1060
1066
|
}
|
|
1061
1067
|
|
|
1062
1068
|
// src/diagnostics.ts
|
|
1063
|
-
function
|
|
1069
|
+
function formatFulgurjsDiagnostic(input) {
|
|
1064
1070
|
const ctx = input.details ? `
|
|
1065
1071
|
\u4E0A\u4E0B\u6587\uFF1A${JSON.stringify(input.details)}` : "";
|
|
1066
|
-
return `[
|
|
1072
|
+
return `[fulgurjs:${input.code}] ${input.symptom}
|
|
1067
1073
|
\u6839\u56E0\uFF1A${input.cause}
|
|
1068
1074
|
\u4FEE\u6CD5\uFF1A${input.fix}` + ctx;
|
|
1069
1075
|
}
|
|
@@ -1087,7 +1093,7 @@ async function isPortReachable(host, port, timeoutMs = 800) {
|
|
|
1087
1093
|
function manifestUrlOf(devEntry) {
|
|
1088
1094
|
try {
|
|
1089
1095
|
const u = new URL(devEntry);
|
|
1090
|
-
u.pathname = u.pathname.replace("@
|
|
1096
|
+
u.pathname = u.pathname.replace("@fulgurjs-entry.js", "@fulgurjs-manifest.json");
|
|
1091
1097
|
return u;
|
|
1092
1098
|
} catch {
|
|
1093
1099
|
return null;
|
|
@@ -1113,7 +1119,7 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1113
1119
|
schema[remote.key] = { exposes, exists: true };
|
|
1114
1120
|
if (exposes.length === 0) {
|
|
1115
1121
|
console.warn(
|
|
1116
|
-
|
|
1122
|
+
formatFulgurjsDiagnostic({
|
|
1117
1123
|
code: "DEV-002",
|
|
1118
1124
|
symptom: `remote "${remote.key}" \u7684 dev manifest \u53EF\u8FBE\u4F46 exposes \u4E3A\u7A7A\uFF08${u.href}\uFF09`,
|
|
1119
1125
|
cause: "remote \u4FA7 federation({ exposes }) \u4E3A\u7A7A\uFF0C\u6216\u5176\u63D2\u4EF6\u7248\u672C\u8FC7\u65E7\u5BFC\u81F4 manifest \u7F3A\u5B57\u6BB5",
|
|
@@ -1125,7 +1131,7 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1125
1131
|
const remoteVersion = manifest?.buildInfo?.version;
|
|
1126
1132
|
if (remoteVersion && remoteVersion !== options.pluginVersion) {
|
|
1127
1133
|
console.warn(
|
|
1128
|
-
|
|
1134
|
+
formatFulgurjsDiagnostic({
|
|
1129
1135
|
code: "DEV-006",
|
|
1130
1136
|
symptom: `\u5BBF\u4E3B\u4E0E remote "${remote.key}" \u7684 @fulgurjs/federation \u7248\u672C\u4E0D\u4E00\u81F4`,
|
|
1131
1137
|
cause: `\u5BBF\u4E3B ${options.pluginVersion} vs \u8FDC\u7A0B ${remoteVersion}\uFF08pnpm tarball \u65AD\u94FE/\u6F0F\u5347\u7EA7\u5E38\u89C1\uFF09`,
|
|
@@ -1139,7 +1145,7 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1139
1145
|
const port = u.port ? Number(u.port) : u.protocol === "https:" ? 443 : 80;
|
|
1140
1146
|
const portOpen = await isPortReachable(u.hostname, port);
|
|
1141
1147
|
console.warn(
|
|
1142
|
-
|
|
1148
|
+
formatFulgurjsDiagnostic({
|
|
1143
1149
|
code: "DEV-001",
|
|
1144
1150
|
symptom: `remote "${remote.key}" \u7684 dev manifest \u4E0D\u53EF\u8FBE\uFF08${u.href}\uFF09\u2014\u2014\u8BE5 remote \u7684\u8DEF\u7531\u5B58\u5728\u6027\u6821\u9A8C\u5C06\u8DF3\u8FC7`,
|
|
1145
1151
|
cause: portOpen ? "\u7AEF\u53E3\u6709\u8FDB\u7A0B\u76D1\u542C\u4F46 manifest \u7AEF\u70B9\u5F02\u5E38\uFF1Aremote dev server \u53EF\u80FD\u4EE5\u975E\u8054\u90A6\u914D\u7F6E\u542F\u52A8\uFF0C\u6216 base/\u8DEF\u5F84\u4E0E remotes[].dev \u4E0D\u4E00\u81F4" : "\u7AEF\u53E3\u65E0\u8FDB\u7A0B\u76D1\u542C\uFF1Aremote dev server \u672A\u542F\u52A8\uFF0C\u6216 remotes[].dev \u7AEF\u53E3\u5199\u9519\uFF08server.origin \u9519\u4F4D\u540C\u6B3E\uFF09",
|
|
@@ -1152,7 +1158,7 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1152
1158
|
return schema;
|
|
1153
1159
|
}
|
|
1154
1160
|
function genEmptyRemoteSchemaModule() {
|
|
1155
|
-
console.info("[
|
|
1161
|
+
console.info("[fulgurjs] build \u671F\u8DF3\u8FC7\u8DEF\u7531 spec \u5B58\u5728\u6027\u6821\u9A8C\uFF08\u8FDC\u7A0B manifest \u4E0D\u5728\u6784\u5EFA\u673A\u672C\u5730\uFF1Bdev \u4E0B\u81EA\u52A8\u542F\u7528\uFF09");
|
|
1156
1162
|
return "export default {}";
|
|
1157
1163
|
}
|
|
1158
1164
|
|
|
@@ -1161,27 +1167,27 @@ import fs3 from "fs";
|
|
|
1161
1167
|
import path4 from "path";
|
|
1162
1168
|
function syncViteCacheMarker(root, pluginVersion, log) {
|
|
1163
1169
|
const viteDir = path4.join(root, "node_modules", ".vite");
|
|
1164
|
-
const marker = path4.join(viteDir, "
|
|
1170
|
+
const marker = path4.join(viteDir, "fulgurjs-version.txt");
|
|
1165
1171
|
try {
|
|
1166
1172
|
if (fs3.existsSync(viteDir)) {
|
|
1167
1173
|
const prev = fs3.existsSync(marker) ? fs3.readFileSync(marker, "utf8").trim() : "";
|
|
1168
1174
|
if (prev === pluginVersion) return;
|
|
1169
1175
|
fs3.rmSync(viteDir, { recursive: true, force: true });
|
|
1170
1176
|
log(
|
|
1171
|
-
`[
|
|
1177
|
+
`[fulgurjs] \u63D2\u4EF6\u7248\u672C\u53D8\u5316\uFF08${prev || "\u65E0\u8BB0\u5F55"} \u2192 ${pluginVersion}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664 ${path4.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`
|
|
1172
1178
|
);
|
|
1173
1179
|
}
|
|
1174
1180
|
fs3.mkdirSync(viteDir, { recursive: true });
|
|
1175
1181
|
fs3.writeFileSync(marker, pluginVersion);
|
|
1176
1182
|
} catch (e) {
|
|
1177
1183
|
log(
|
|
1178
|
-
`[
|
|
1184
|
+
`[fulgurjs] \u81EA\u52A8\u6E05\u7406 .vite \u7F13\u5B58\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u542F\u52A8\uFF1B\u5982\u9047\u8054\u90A6\u6A21\u5757 404 \u8BF7\u624B\u5DE5\u6267\u884C rm -rf ${viteDir}\uFF09\uFF1A${String(e.message ?? e)}`
|
|
1179
1185
|
);
|
|
1180
1186
|
}
|
|
1181
1187
|
}
|
|
1182
1188
|
|
|
1183
1189
|
// src/runtime-code.gen.ts
|
|
1184
|
-
var runtime_code_gen_default = 'var Q=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function k(t){let n=Q.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 ee(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),w=/^\\d+$/.test(m);if(y&&w){let M=Number(l)-Number(m);if(M!==0)return M}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function T(t,n){let o=k(t),r=k(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:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function N(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!k(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!N(t,`>=${m}`)||!N(t,`<=${y}`))}let r=k(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(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 ne(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],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(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 ie(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 ae(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 w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")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 se(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 ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(T(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(T(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=T(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(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(`[fulgur:${n}] ${o}`),this.name="FulgurError",this.code=n,this.details=r}},R={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 F="0.4.2";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGUR_APP_CONFIG__=m)}function w(){return m}let M={},D=()=>{for(let e of o)try{e.init?.(M)}catch(i){console.warn("[fulgur] runtimePlugin init failed:",e.name,i)}},I=e=>t[e]??={};function $(e){try{M.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgur:error",{detail:e}))}function H(e="default"){return I(e),t}function K(e,i,a,u,E={}){let s=I(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=I(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||N(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(T).pop(),c.length>1||!f.includes(b)){let h=s[b],O=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let v=new g(R.SHARE_STRICT_VERSION,O,{shareKey:u,requiredVersion:d});throw $({remote:h.from,error:v}),v}console.warn(`[fulgur:MFU-010] ${O}`)}}else if(b=[...f].sort(T).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw $({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw $({remote:u,error:p}),p}let _=s[b];if(M.resolveShare){let p=await M.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function W(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let B=e=>new Promise(i=>setTimeout(i,e));function j(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(`[fulgur] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return W(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.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 u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw $({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return j(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return j(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let O=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-O),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(v){if(d=v,v?.code)throw v;h<b&&await B(200*2**h)}}if(f)break}if(!f||!c){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 (fulgur-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(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}j(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw $({remote:e.name,error:s}),s;if(s?.code)throw $({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw $({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:X(e.slice(i+1))}}function X(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:u}=A(e);M.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgur] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),$({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}catch(f){if(i?.fallbackModule)return console.error(`[fulgur] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),$({remote:a,error:f}),await i.fallbackModule();throw f}if(M.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});$({remote:a,error:f}),console.error(`[fulgur:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){$({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{remote:a})})}}return typeof window>"u"||(window.__FULGUR_SCOPE__=t,window.__FULGUR_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:J,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurAppConfig:y,getFulgurAppConfig:w}}var V=globalThis,S=V.__FULGUR_RUNTIME__??fe();V.__FULGUR_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,$e=S.registerRemote,Me=S.registerPlugins,ve=S.loadShare,Te=S.loadRemote,Oe=S.getContainer,ke=S.preloadRemote,Ne=S.shareScopeMap,Ie=S.provideFulgurAppConfig,je=S.getFulgurAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Oe as getContainer,je as getFulgurAppConfig,Se as getRuntime,we as initSharing,Te as loadRemote,ve as loadShare,ke as preloadRemote,Ie as provideFulgurAppConfig,Me as registerPlugins,$e as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,Ne as shareScopeMap,Ae as unwrapDefault,Re as version};\n';
|
|
1190
|
+
var runtime_code_gen_default = 'var Q=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.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 ee(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),w=/^\\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(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:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(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 ne(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],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(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 ie(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 ae(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 w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")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 se(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 ue(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=se(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="FulgurjsError",this.code=n,this.details=r}},R={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 F="0.5.1";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGURJS_APP_CONFIG__=m)}function w(){return m}let $={},D=()=>{for(let e of o)try{e.init?.($)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},N=e=>t[e]??={};function j(e){try{$.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function H(e="default"){return N(e),t}function K(e,i,a,u,E={}){let s=N(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=N(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||k(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(v).pop(),c.length>1||!f.includes(b)){let h=s[b],T=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let M=new g(R.SHARE_STRICT_VERSION,T,{shareKey:u,requiredVersion:d});throw j({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${T}`)}}else if(b=[...f].sort(v).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw j({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw j({remote:u,error:p}),p}let _=s[b];if($.resolveShare){let p=await $.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function J(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let W=e=>new Promise(i=>setTimeout(i,e));function I(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:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return J(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.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 u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw j({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return I(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return I(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let T=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-T),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<b&&await W(200*2**h)}}if(f)break}if(!f||!c){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(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}I(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw j({remote:e.name,error:s}),s;if(s?.code)throw j({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw j({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:B(e.slice(i+1))}}function B(e){return e?e.startsWith(".")?e:`./${e}`:""}async function X(e,i){let{remote:a,module:u}=A(e);$.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{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),j({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}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),j({remote:a,error:f}),await i.fallbackModule();throw f}if($.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});j({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){j({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{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:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:X,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurjsAppConfig:y,getFulgurjsAppConfig:w}}var V=globalThis,S=V.__FULGURJS_RUNTIME__??fe();V.__FULGURJS_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,je=S.registerRemote,$e=S.registerPlugins,Me=S.loadShare,ve=S.loadRemote,Te=S.getContainer,Oe=S.preloadRemote,ke=S.shareScopeMap,Ne=S.provideFulgurjsAppConfig,Ie=S.getFulgurjsAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Te as getContainer,Ie as getFulgurjsAppConfig,Se as getRuntime,we as initSharing,ve as loadRemote,Me as loadShare,Oe as preloadRemote,Ne as provideFulgurjsAppConfig,$e as registerPlugins,je as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,ke as shareScopeMap,Ae as unwrapDefault,Re as version};\n';
|
|
1185
1191
|
|
|
1186
1192
|
// src/index.ts
|
|
1187
1193
|
function readRuntimeCode() {
|
|
@@ -1191,7 +1197,7 @@ function normalizeBase(base) {
|
|
|
1191
1197
|
if (!base || base === "/") return "/";
|
|
1192
1198
|
return base.endsWith("/") ? base : `${base}/`;
|
|
1193
1199
|
}
|
|
1194
|
-
var
|
|
1200
|
+
var FULGURJS_STUB_NAMESPACE = "fulgurjs-opt-stub";
|
|
1195
1201
|
var nsExportCache = /* @__PURE__ */ new Map();
|
|
1196
1202
|
function enumerateCjsExports(packageName, appRoot) {
|
|
1197
1203
|
const cached = nsExportCache.get(packageName);
|
|
@@ -1203,7 +1209,7 @@ function enumerateCjsExports(packageName, appRoot) {
|
|
|
1203
1209
|
names = Object.keys(mod);
|
|
1204
1210
|
} catch {
|
|
1205
1211
|
console.warn(
|
|
1206
|
-
`[
|
|
1212
|
+
`[fulgurjs] cannot enumerate CJS exports of shared package "${packageName}" for the optimize-deps facade; the facade will export default only. If consumers destructure named exports from it, add this package to optimizeDeps.exclude to serve it through the transform pipeline instead.`
|
|
1207
1213
|
);
|
|
1208
1214
|
}
|
|
1209
1215
|
nsExportCache.set(packageName, names);
|
|
@@ -1235,7 +1241,7 @@ function federation(options) {
|
|
|
1235
1241
|
entryInitInjected: /* @__PURE__ */ new Set()
|
|
1236
1242
|
};
|
|
1237
1243
|
const pre = {
|
|
1238
|
-
name: "
|
|
1244
|
+
name: "fulgurjs:core",
|
|
1239
1245
|
enforce: "pre",
|
|
1240
1246
|
async config(userConfig, env) {
|
|
1241
1247
|
state.command = env.command;
|
|
@@ -1254,19 +1260,19 @@ function federation(options) {
|
|
|
1254
1260
|
const filter = new RegExp(`^(${[...aliasToShare.keys()].map(escapeRe).join("|")})$`);
|
|
1255
1261
|
const devBase = normalizeBase(userConfig.base ?? "/");
|
|
1256
1262
|
const sharedExternal = {
|
|
1257
|
-
name: "
|
|
1263
|
+
name: "fulgurjs:optimize-shared-external",
|
|
1258
1264
|
setup(build) {
|
|
1259
|
-
const facadeUrlFor = (shareKey) => `${devBase}@id/__x00__virtual:
|
|
1265
|
+
const facadeUrlFor = (shareKey) => `${devBase}@id/__x00__virtual:fulgurjs-shared-ns:${shareKey}?import`;
|
|
1260
1266
|
const b = build;
|
|
1261
|
-
b.onResolve({ filter: /
|
|
1267
|
+
b.onResolve({ filter: /fulgurjs-shared-ns:/ }, (args) => ({ path: args.path, external: true }));
|
|
1262
1268
|
b.onResolve({ filter }, (args) => {
|
|
1263
1269
|
if (args.kind === "entry-point" || args.kind === "entry-point-render") return null;
|
|
1264
1270
|
const s = aliasToShare.get(args.path);
|
|
1265
1271
|
if (!s) return null;
|
|
1266
|
-
return { path: `
|
|
1272
|
+
return { path: `fulgurjs-stub:${s.shareKey}`, namespace: FULGURJS_STUB_NAMESPACE };
|
|
1267
1273
|
});
|
|
1268
|
-
b.onLoad({ filter: /^
|
|
1269
|
-
const shareKey = args.path.slice("
|
|
1274
|
+
b.onLoad({ filter: /^fulgurjs-stub:/, namespace: FULGURJS_STUB_NAMESPACE }, (args) => {
|
|
1275
|
+
const shareKey = args.path.slice("fulgurjs-stub:".length);
|
|
1270
1276
|
const url = facadeUrlFor(shareKey);
|
|
1271
1277
|
return {
|
|
1272
1278
|
contents: `export * from ${JSON.stringify(url)};
|
|
@@ -1293,7 +1299,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1293
1299
|
if (userTarget) {
|
|
1294
1300
|
if (/es20(0\d|1\d|20|21)/.test(String(userTarget))) {
|
|
1295
1301
|
normalized.warnings.push(
|
|
1296
|
-
`build.target="${String(userTarget)}" does not support top-level await;
|
|
1302
|
+
`build.target="${String(userTarget)}" does not support top-level await; fulgurjs requires es2022 or higher.`
|
|
1297
1303
|
);
|
|
1298
1304
|
}
|
|
1299
1305
|
} else {
|
|
@@ -1301,13 +1307,13 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1301
1307
|
extra.build = { target: "es2022" };
|
|
1302
1308
|
}
|
|
1303
1309
|
}
|
|
1304
|
-
for (const w of normalized.warnings) console.warn(`[
|
|
1310
|
+
for (const w of normalized.warnings) console.warn(`[fulgurjs] ${w}`);
|
|
1305
1311
|
return extra;
|
|
1306
1312
|
},
|
|
1307
1313
|
configResolved(resolved) {
|
|
1308
1314
|
state.base = normalizeBase(resolved.base);
|
|
1309
1315
|
if (resolved.build?.ssr) {
|
|
1310
|
-
console.warn("[
|
|
1316
|
+
console.warn("[fulgurjs] SSR builds are not supported in this version; plugin hooks disabled.");
|
|
1311
1317
|
}
|
|
1312
1318
|
const n0 = state.normalized;
|
|
1313
1319
|
const optimize = resolved.optimizeDeps;
|
|
@@ -1320,7 +1326,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1320
1326
|
for (const pkg of KNOWN_UMD) {
|
|
1321
1327
|
if (n0.pkgDependencies[pkg] && !incl(pkg) && !excl(pkg)) {
|
|
1322
1328
|
console.warn(
|
|
1323
|
-
|
|
1329
|
+
formatFulgurjsDiagnostic({
|
|
1324
1330
|
code: "DEV-004",
|
|
1325
1331
|
symptom: `UMD-only \u4F9D\u8D56 "${pkg}" \u4E0D\u5728 optimizeDeps.include`,
|
|
1326
1332
|
cause: "UMD \u5305\u53EA\u80FD\u7ECF\u9884\u6784\u5EFA\u6D88\u8D39\uFF1B\u4E0D\u58F0\u660E\u4F1A\u88AB\u88F8 CJS \u670D\u52A1\u6216\u5185\u8054\u672C\u5730 vue\uFF08\u9875\u9762\u7A7A\u767D/\u53CC\u5B9E\u4F8B\uFF09",
|
|
@@ -1349,7 +1355,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1349
1355
|
if (!known && !warnedUnknownPrefixes.has(prefix)) {
|
|
1350
1356
|
warnedUnknownPrefixes.add(prefix);
|
|
1351
1357
|
console.warn(
|
|
1352
|
-
`[
|
|
1358
|
+
`[fulgurjs] "${source}" uses prefix "${prefix}/", which is not in federation({ remotes }) or shared. If "${prefix}" is a federated remote, add it: remotes: { '${prefix}': '<url>' }. (Ignore this if it is a plain npm package.)`
|
|
1353
1359
|
);
|
|
1354
1360
|
}
|
|
1355
1361
|
}
|
|
@@ -1357,17 +1363,17 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1357
1363
|
if (bareClean === RUNTIME_VIRTUAL_ID) return RESOLVED.runtime;
|
|
1358
1364
|
if (bareClean === RUNTIME_PROXY_VIRTUAL_ID) return RESOLVED.runtimeProxy;
|
|
1359
1365
|
if (bareClean === INIT_VIRTUAL_ID) return RESOLVED.init;
|
|
1360
|
-
if (bareClean === "virtual:
|
|
1361
|
-
if (bareClean === "virtual:
|
|
1362
|
-
if (bareClean === "virtual:
|
|
1366
|
+
if (bareClean === "virtual:fulgurjs-remote-schema") return bareClean;
|
|
1367
|
+
if (bareClean === "virtual:fulgurjs-provides") return RESOLVED.provides;
|
|
1368
|
+
if (bareClean === "virtual:fulgurjs-remote-entry") return RESOLVED.remoteEntry;
|
|
1363
1369
|
if (bareClean.startsWith(SHARED_NS_FACADE_PREFIX)) {
|
|
1364
1370
|
return RESOLVED.sharedNsFacade(bareClean.slice(SHARED_NS_FACADE_PREFIX.length)) + query;
|
|
1365
1371
|
}
|
|
1366
|
-
if (bareClean.startsWith("virtual:
|
|
1367
|
-
return RESOLVED.sharedNsFacade(bareClean.slice("virtual:
|
|
1372
|
+
if (bareClean.startsWith("virtual:fulgurjs-cjs-ns:")) {
|
|
1373
|
+
return RESOLVED.sharedNsFacade(bareClean.slice("virtual:fulgurjs-cjs-ns:".length)) + query;
|
|
1368
1374
|
}
|
|
1369
|
-
if (bareClean.startsWith("virtual:
|
|
1370
|
-
const body = bareClean.slice("virtual:
|
|
1375
|
+
if (bareClean.startsWith("virtual:fulgurjs-shared:")) {
|
|
1376
|
+
const body = bareClean.slice("virtual:fulgurjs-shared:".length);
|
|
1371
1377
|
return RESOLVED.sharedFacade(body) + query;
|
|
1372
1378
|
}
|
|
1373
1379
|
return null;
|
|
@@ -1376,22 +1382,22 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1376
1382
|
const raw = id.startsWith("\0") ? id.slice(1) : id;
|
|
1377
1383
|
const q = raw.indexOf("?");
|
|
1378
1384
|
const clean = q === -1 ? raw : raw.slice(0, q);
|
|
1379
|
-
if (clean === "virtual:
|
|
1385
|
+
if (clean === "virtual:fulgurjs-runtime") return readRuntimeCode();
|
|
1380
1386
|
if (clean === RESOLVED.runtimeProxy || clean === RUNTIME_PROXY_VIRTUAL_ID) return genRuntimeProxyModule();
|
|
1381
|
-
if (clean === "virtual:
|
|
1387
|
+
if (clean === "virtual:fulgurjs-init" && state.normalized) {
|
|
1382
1388
|
return genInitModule(state.normalized, state.command);
|
|
1383
1389
|
}
|
|
1384
|
-
if (clean === "virtual:
|
|
1390
|
+
if (clean === "virtual:fulgurjs-provides" && state.normalized) {
|
|
1385
1391
|
return genDevProvides(state.normalized);
|
|
1386
1392
|
}
|
|
1387
|
-
if (clean === "virtual:
|
|
1393
|
+
if (clean === "virtual:fulgurjs-remote-schema" && state.normalized) {
|
|
1388
1394
|
if (state.command === "build") return genEmptyRemoteSchemaModule();
|
|
1389
1395
|
remoteSchemaPromise ??= probeRemotesAndBuildSchema(state.normalized).then(
|
|
1390
1396
|
(schema) => `export default ${JSON.stringify(schema)}`
|
|
1391
1397
|
);
|
|
1392
1398
|
return remoteSchemaPromise;
|
|
1393
1399
|
}
|
|
1394
|
-
if (clean === "virtual:
|
|
1400
|
+
if (clean === "virtual:fulgurjs-remote-entry" && state.normalized) {
|
|
1395
1401
|
return genBuildRemoteEntry(state.normalized, state.exposeAbsPaths);
|
|
1396
1402
|
}
|
|
1397
1403
|
if (clean.startsWith(SHARED_NS_FACADE_PREFIX) && state.normalized) {
|
|
@@ -1406,8 +1412,8 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1406
1412
|
}
|
|
1407
1413
|
return genSharedNsFacade(item, serializeShareCallForFacade(item), names);
|
|
1408
1414
|
}
|
|
1409
|
-
if (clean.startsWith("virtual:
|
|
1410
|
-
const body = clean.slice("virtual:
|
|
1415
|
+
if (clean.startsWith("virtual:fulgurjs-shared:") && state.normalized) {
|
|
1416
|
+
const body = clean.slice("virtual:fulgurjs-shared:".length);
|
|
1411
1417
|
const f = raw.indexOf("?f=");
|
|
1412
1418
|
if (f === -1) {
|
|
1413
1419
|
const item2 = state.normalized.shared.find((x) => x.shareKey === body);
|
|
@@ -1432,7 +1438,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1432
1438
|
...item.strictVersion ? ["strictVersion: true"] : [],
|
|
1433
1439
|
"fallback: () => import(" + JSON.stringify(item.import) + ")"
|
|
1434
1440
|
];
|
|
1435
|
-
const call = "
|
|
1441
|
+
const call = "__fulgurjs_loadShare(" + JSON.stringify(item.shareKey) + ", { " + opts.join(", ") + " })";
|
|
1436
1442
|
return genBindingFacade(item, entry.bindings, call);
|
|
1437
1443
|
}
|
|
1438
1444
|
return null;
|
|
@@ -1497,12 +1503,12 @@ ${code}`, map: null };
|
|
|
1497
1503
|
if (resolved) {
|
|
1498
1504
|
state.exposeAbsPaths[e.import] = resolved.id.split("?")[0];
|
|
1499
1505
|
} else {
|
|
1500
|
-
this.error(`[
|
|
1506
|
+
this.error(`[fulgurjs] expose "${e.import}" could not be resolved from ${n.root}`);
|
|
1501
1507
|
}
|
|
1502
1508
|
}
|
|
1503
1509
|
this.emitFile({
|
|
1504
1510
|
type: "chunk",
|
|
1505
|
-
id: "virtual:
|
|
1511
|
+
id: "virtual:fulgurjs-remote-entry",
|
|
1506
1512
|
fileName: n.filename.replace(/^\//, ""),
|
|
1507
1513
|
preserveSignature: "allow-extension"
|
|
1508
1514
|
});
|
|
@@ -1532,7 +1538,7 @@ ${code}`, map: null };
|
|
|
1532
1538
|
const manifest = genProdManifest(n, state.exposeFiles, entryChunkName ?? n.filename);
|
|
1533
1539
|
this.emitFile({
|
|
1534
1540
|
type: "asset",
|
|
1535
|
-
fileName: "
|
|
1541
|
+
fileName: "fulgurjs-manifest.json",
|
|
1536
1542
|
source: JSON.stringify(manifest, null, 2)
|
|
1537
1543
|
});
|
|
1538
1544
|
},
|
|
@@ -1542,10 +1548,10 @@ ${code}`, map: null };
|
|
|
1542
1548
|
warmResolvedSharedPaths(server);
|
|
1543
1549
|
if (n.exposes.length > 0 || n.remotes.length > 0) {
|
|
1544
1550
|
console.warn(
|
|
1545
|
-
|
|
1551
|
+
formatFulgurjsDiagnostic({
|
|
1546
1552
|
code: "DEV-010",
|
|
1547
1553
|
symptom: 'dev \u51B7\u542F\u52A8\u9884\u6784\u5EFA\u7A97\u53E3\uFF1A\u9996\u6B21\u542F\u52A8\u6216\u6E05 node_modules/.vite \u540E\u9996\u8F6E 30~60s \u5185\uFF0C\u8054\u90A6\u6A21\u5757\u8BF7\u6C42\u53EF\u80FD\u51FA\u73B0\u77AC\u65F6 504 / "ce" / Outdated Optimize Dep',
|
|
1548
|
-
cause: "vite \u4F9D\u8D56\u9884\u6784\u5EFA\uFF08\u542B
|
|
1554
|
+
cause: "vite \u4F9D\u8D56\u9884\u6784\u5EFA\uFF08\u542B fulgurjs \u5916\u90E8\u5316\u6869\uFF09\u5C1A\u672A\u5C31\u7EEA\uFF0C\u5C5E\u9884\u6784\u5EFA\u6682\u6001\u800C\u975E\u56DE\u5F52\uFF1B\u9996\u8F6E\u7ED3\u675F\u540E\u81EA\u884C\u6062\u590D",
|
|
1549
1555
|
fix: "\u5148\u771F\u5B9E\u6253\u5F00\u4E00\u6B21\u9875\u9762\u9884\u70ED\uFF08\u7B49\u5230\u7F51\u7EDC\u7A7A\u95F2\uFF09\uFF0C\u518D\u505A\u9A8C\u6536\u65AD\u8A00\u6216\u4EBA\u5DE5\u5224\u65AD\uFF1B\u91CD\u590D\u51FA\u73B0\u624D\u6309 DEV-009 \u6E05\u7F13\u5B58\u6392\u67E5"
|
|
1550
1556
|
})
|
|
1551
1557
|
);
|
|
@@ -1555,7 +1561,7 @@ ${code}`, map: null };
|
|
|
1555
1561
|
server.middlewares.use((req, res, next) => {
|
|
1556
1562
|
const raw = (req.url ?? "").split("?")[0];
|
|
1557
1563
|
const stripped = raw.startsWith(baseNorm) ? `/${raw.slice(baseNorm.length)}` : raw;
|
|
1558
|
-
if (stripped === "/@
|
|
1564
|
+
if (stripped === "/@fulgurjs-entry.js" || stripped === "/@fulgurjs-manifest.json") {
|
|
1559
1565
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
1560
1566
|
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
|
|
1561
1567
|
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
@@ -1564,7 +1570,7 @@ ${code}`, map: null };
|
|
|
1564
1570
|
res.end();
|
|
1565
1571
|
return;
|
|
1566
1572
|
}
|
|
1567
|
-
if (stripped === "/@
|
|
1573
|
+
if (stripped === "/@fulgurjs-entry.js") {
|
|
1568
1574
|
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
1569
1575
|
res.setHeader("Cache-Control", "no-cache");
|
|
1570
1576
|
res.end(genDevRemoteEntry(n, baseNorm));
|
|
@@ -1594,10 +1600,10 @@ ${code}`, map: null };
|
|
|
1594
1600
|
return () => {
|
|
1595
1601
|
server.middlewares.use((req, res, next) => {
|
|
1596
1602
|
const url = req.url ?? "";
|
|
1597
|
-
if (req.method === "GET" && url.includes("
|
|
1603
|
+
if (req.method === "GET" && url.includes("fulgurjs")) {
|
|
1598
1604
|
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
1599
1605
|
res.end(
|
|
1600
|
-
|
|
1606
|
+
formatFulgurjsDiagnostic({
|
|
1601
1607
|
code: "DEV-009",
|
|
1602
1608
|
symptom: `\u8054\u90A6\u6A21\u5757\u8BF7\u6C42 404\uFF1A${url.slice(0, 120)}`,
|
|
1603
1609
|
cause: "node_modules/.vite \u9884\u6784\u5EFA\u7F13\u5B58\u4E0E\u5F53\u524D\u63D2\u4EF6\u4EA7\u7269\u4E0D\u4E00\u81F4\uFF08immutable \u7F13\u5B58\u6309 ?f= \u7B7E\u540D\u957F\u671F\u6301\u6709\uFF0C\u63D2\u4EF6 dist \u66F4\u65B0\u540E\u65E7\u7B7E\u540D\u5FC5 404\uFF09",
|
|
@@ -1612,15 +1618,15 @@ ${code}`, map: null };
|
|
|
1612
1618
|
}
|
|
1613
1619
|
};
|
|
1614
1620
|
const post = {
|
|
1615
|
-
name: "
|
|
1621
|
+
name: "fulgurjs:vue-post",
|
|
1616
1622
|
enforce: "post",
|
|
1617
1623
|
async transform(code, id) {
|
|
1618
1624
|
if (!state.normalized) return null;
|
|
1619
1625
|
const clean = id.split("?")[0];
|
|
1620
|
-
if (state.command === "serve" && code.includes("virtual:
|
|
1621
|
-
return { code: code.split("virtual:
|
|
1626
|
+
if (state.command === "serve" && code.includes("virtual:fulgurjs-runtime") && !code.includes("virtual:fulgurjs-runtime-proxy") && isExposeTargetFile(clean, state.normalized.root, state.normalized.exposes)) {
|
|
1627
|
+
return { code: code.split("virtual:fulgurjs-runtime").join("virtual:fulgurjs-runtime-proxy"), map: null };
|
|
1622
1628
|
}
|
|
1623
|
-
if (code
|
|
1629
|
+
if (isPluginProcessedModule(code)) return null;
|
|
1624
1630
|
if (state.command === "build" && !/\.vue(\?|$)/.test(id)) return null;
|
|
1625
1631
|
if (/type=(style|template)/.test(id)) return null;
|
|
1626
1632
|
const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
|