@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/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/config.ts
|
|
13
|
-
async function
|
|
13
|
+
async function loadFulgurjsConfig(configPath) {
|
|
14
14
|
const { pathToFileURL, fileURLToPath } = await import("node:url");
|
|
15
15
|
const { createRequire } = await import("node:module");
|
|
16
16
|
const fs2 = await import("node:fs");
|
|
@@ -18,8 +18,8 @@ async function loadFulgurConfig(configPath) {
|
|
|
18
18
|
const path2 = await import("node:path");
|
|
19
19
|
const selfDir = path2.dirname(fileURLToPath(import.meta.url));
|
|
20
20
|
const selfConfigJs = path2.join(selfDir, "config.js");
|
|
21
|
-
const SELF_SPEC = fs2.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@
|
|
22
|
-
const rewriteSelfImports = (source) => source.replace(/(['"])@
|
|
21
|
+
const SELF_SPEC = fs2.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@fulgurjs-federation-config-unavailable";
|
|
22
|
+
const rewriteSelfImports = (source) => source.replace(/(['"])@fulgurjs\/federation\/config\1/g, (_m, q) => `${q}${SELF_SPEC}${q}`);
|
|
23
23
|
const importConfigs = async (cacheKey) => {
|
|
24
24
|
return await import(`${cacheKey}?t=${Date.now()}`);
|
|
25
25
|
};
|
|
@@ -28,7 +28,7 @@ async function loadFulgurConfig(configPath) {
|
|
|
28
28
|
mod = { default: JSON.parse(fs2.readFileSync(configPath, "utf8")) };
|
|
29
29
|
} else {
|
|
30
30
|
const source = rewriteSelfImports(fs2.readFileSync(configPath, "utf8"));
|
|
31
|
-
const tmpBase = path2.join(os.tmpdir(), `
|
|
31
|
+
const tmpBase = path2.join(os.tmpdir(), `fulgurjs-config-${Date.now()}`);
|
|
32
32
|
if (/\.(ts|mts|cts)$/.test(configPath)) {
|
|
33
33
|
try {
|
|
34
34
|
const tmpTs = `${tmpBase}.ts`;
|
|
@@ -60,18 +60,18 @@ async function loadFulgurConfig(configPath) {
|
|
|
60
60
|
const cfg = mod.default;
|
|
61
61
|
if (!cfg?.root) {
|
|
62
62
|
throw new Error(
|
|
63
|
-
`[
|
|
63
|
+
`[fulgurjs:init] \u914D\u7F6E\u7F3A\u5C11 root\uFF08\u5DE5\u7A0B\u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF09
|
|
64
64
|
\u6839\u56E0\uFF1ACLI \u9700\u8981\u77E5\u9053\u5728\u54EA\u4E2A\u5DE5\u7A0B\u4E0A\u505A\u96C6\u6210
|
|
65
|
-
\u4FEE\u6CD5\
|
|
65
|
+
\u4FEE\u6CD5\uFF1Afulgurjs.config.ts \u9876\u5C42\u8865 root: '/abs/path/to/repo'\uFF08\u8D77\u6B65\u6A21\u677F\uFF1Afulgurjs init\uFF09`
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
if (!Array.isArray(cfg.apps) || cfg.apps.length === 0) {
|
|
69
|
-
throw new Error("[
|
|
69
|
+
throw new Error("[fulgurjs:init] \u914D\u7F6E\u7F3A\u5C11 apps\uFF08\u81F3\u5C11\u4E00\u4E2A\u5BBF\u4E3B\u6216\u8FDC\u7A0B\u5E94\u7528\uFF09");
|
|
70
70
|
}
|
|
71
71
|
for (const app of cfg.apps) {
|
|
72
72
|
if (!app.host && !app.remote) {
|
|
73
73
|
throw new Error(
|
|
74
|
-
`[
|
|
74
|
+
`[fulgurjs:init] \u5E94\u7528 "${app.path}" \u65E2\u65E0 host \u4E5F\u65E0 remote \u89D2\u8272
|
|
75
75
|
\u6839\u56E0\uFF1A\u5E94\u7528\u5FC5\u987B\u81F3\u5C11\u58F0\u660E\u4E00\u4E2A\u89D2\u8272
|
|
76
76
|
\u4FEE\u6CD5\uFF1A\u5BBF\u4E3B\u8865 host: { pages, remotePrefixes, remotes }\uFF0C\u8FDC\u7A0B\u8865 remote: { exposes }`
|
|
77
77
|
);
|
|
@@ -142,11 +142,11 @@ function nginxSnippetFor(cfg) {
|
|
|
142
142
|
return ` location ${b} {
|
|
143
143
|
try_files $uri $uri/ ${hostIndex};
|
|
144
144
|
|
|
145
|
-
location = ${b}/
|
|
145
|
+
location = ${b}/fulgurjs-remoteEntry.js {
|
|
146
146
|
add_header Cache-Control "no-cache";
|
|
147
147
|
add_header Access-Control-Allow-Origin "*";
|
|
148
148
|
}
|
|
149
|
-
location = ${b}/
|
|
149
|
+
location = ${b}/fulgurjs-manifest.json {
|
|
150
150
|
add_header Cache-Control "no-cache";
|
|
151
151
|
add_header Access-Control-Allow-Origin "*";
|
|
152
152
|
}
|
|
@@ -187,7 +187,7 @@ function appSummary(app) {
|
|
|
187
187
|
return lines.join("\n");
|
|
188
188
|
}
|
|
189
189
|
async function inspectConfig(configPath) {
|
|
190
|
-
const cfg = await
|
|
190
|
+
const cfg = await loadFulgurjsConfig(configPath);
|
|
191
191
|
const out = [];
|
|
192
192
|
out.push(`${MARK} \u914D\u7F6E\u6821\u9A8C\u901A\u8FC7\uFF1Aroot=${cfg.root}\uFF0Capps=${cfg.apps.length}`);
|
|
193
193
|
out.push("\u5E94\u7528\u6458\u8981\uFF1A");
|
|
@@ -205,10 +205,10 @@ async function inspectConfig(configPath) {
|
|
|
205
205
|
out.push("2. expose \u4E00\u5F8B\u6307\u5411\u72EC\u7ACB\u9875\uFF08\u9875\u9762\u4ECE\u8DEF\u7531\u53D6\u53C2\uFF09\uFF1B\u7EC4\u4EF6\u9700\u8981\u5FC5\u586B props \u65F6\u7ED9\u9ED8\u8BA4\u503C\uFF08BLD-003\uFF09");
|
|
206
206
|
out.push("3. shared \u91CC vue / vue-router / pinia \u5EFA\u8BAE singleton: true\u2014\u2014\u8DE8\u5E94\u7528\u5FC5\u987B\u540C\u5B9E\u4F8B\uFF08\u5168\u5C40\u54CD\u5E94\u6027\u3001getActivePinia\u3001\u8DEF\u7531\u6CE8\u5165\uFF09");
|
|
207
207
|
out.push("4. \u8FDC\u7A0B\u7684\u5168\u5C40\u526F\u4F5C\u7528\uFF08\u5168\u5C40\u7EC4\u4EF6/\u6307\u4EE4/\u542F\u52A8\u671F\u521D\u59CB\u5316\uFF09\u5C01\u88C5\u4E3A\u542F\u52A8\u5668\u6A21\u5757\u5E76 expose\uFF0C\u5BBF\u4E3B\u5728 loadRemote \u9875\u9762\u524D\u8C03\u7528\uFF1B");
|
|
208
|
-
out.push(" \u8DE8\u5E94\u7528\u5168\u5C40\u914D\u7F6E\uFF08locale/size \u7B49\uFF09\u7528\u8FD0\u884C\u65F6
|
|
209
|
-
out.push("5. \u8FDC\u7A0B\u9875\u9762\u53D6\u5BBF\u4E3B\u8FD0\u884C\u65F6\u4E00\u5F8B\u8D70 globalThis.
|
|
208
|
+
out.push(" \u8DE8\u5E94\u7528\u5168\u5C40\u914D\u7F6E\uFF08locale/size \u7B49\uFF09\u7528\u8FD0\u884C\u65F6 provideFulgurjsAppConfig / getFulgurjsAppConfig \u534F\u5546\uFF0C\u4E0D\u8981\u5404\u526F\u672C\u624B\u5DE5\u6CE8\u5165");
|
|
209
|
+
out.push("5. \u8FDC\u7A0B\u9875\u9762\u53D6\u5BBF\u4E3B\u8FD0\u884C\u65F6\u4E00\u5F8B\u8D70 globalThis.__FULGURJS_RUNTIME__ / getRuntime()\uFF0C\u7981\u6B62\u9759\u6001\u5BFC\u5165\u865A\u62DF\u8FD0\u884C\u65F6\uFF08DEV-008\uFF09");
|
|
210
210
|
out.push('6. dev \u51B7\u542F\u52A8\u9996\u8F6E 30~60s \u6709\u9884\u6784\u5EFA\u7A97\u53E3\uFF08\u77AC\u65F6 504/"ce"\uFF0CDEV-010\uFF09\uFF1A\u5148\u771F\u5B9E\u6253\u5F00\u9875\u9762\u9884\u70ED\u518D\u505A\u65AD\u8A00');
|
|
211
|
-
out.push("7. \u90E8\u7F72\u540E\u4F53\u68C0\
|
|
211
|
+
out.push("7. \u90E8\u7F72\u540E\u4F53\u68C0\uFF1Afulgurjs doctor --base <URL> --apps <\u5E94\u7528...>\uFF08\u7F13\u5B58\u5934/\u8D44\u6E90\u5F62\u6001/CORS/chunk \u53EF\u8FBE/\u7248\u672C skew\uFF09");
|
|
212
212
|
out.push("8. \u90E8\u7F72\u8BED\u4E49\uFF1AremoteEntry/manifest/index.html \u5FC5\u987B no-cache\uFF08\u4E25\u7981 immutable\uFF09\uFF1B\u5E26 hash \u7684 assets \u957F\u7F13\u5B58");
|
|
213
213
|
return out.join("\n");
|
|
214
214
|
}
|
|
@@ -217,13 +217,13 @@ var init_init = __esm({
|
|
|
217
217
|
"src/init.ts"() {
|
|
218
218
|
"use strict";
|
|
219
219
|
init_config();
|
|
220
|
-
MARK = "[
|
|
221
|
-
STARTER_CONFIG = `//
|
|
222
|
-
// \u7528\u6CD5\uFF1Anpx
|
|
223
|
-
// npx
|
|
224
|
-
import {
|
|
220
|
+
MARK = "[fulgurjs:init]";
|
|
221
|
+
STARTER_CONFIG = `// fulgurjs.config.ts \u2014\u2014 @fulgurjs/federation \u63A5\u5165\u914D\u7F6E\uFF08\u5355\u6587\u4EF6\u9A71\u52A8\uFF0C\u53EF\u5165\u5E93\u3001\u53EF\u590D\u8DD1\uFF09
|
|
222
|
+
// \u7528\u6CD5\uFF1Anpx fulgurjs init --config fulgurjs.config.ts \u6821\u9A8C\u914D\u7F6E\u5E76\u8F93\u51FA\u53EF\u7C98\u8D34\u6837\u677F\u4E0E\u6838\u5BF9\u6E05\u5355
|
|
223
|
+
// npx fulgurjs doctor --base http://<\u7AD9\u70B9> --apps <\u5E94\u7528\u76EE\u5F55\u540D...> \u90E8\u7F72\u4F53\u68C0
|
|
224
|
+
import { defineFulgurjsConfig } from '@fulgurjs/federation/config'
|
|
225
225
|
|
|
226
|
-
export default
|
|
226
|
+
export default defineFulgurjsConfig({
|
|
227
227
|
// \u5DE5\u7A0B\u6839\u76EE\u5F55\uFF08monorepo \u6839\u6216\u5355\u5E94\u7528\u4ED3\u5E93\u6839\uFF09
|
|
228
228
|
root: process.cwd(),
|
|
229
229
|
apps: [
|
|
@@ -424,7 +424,7 @@ async function runDoctor(opts) {
|
|
|
424
424
|
const chunkSample = opts.chunkSample ?? 16;
|
|
425
425
|
for (const app of opts.apps) {
|
|
426
426
|
const root = `${opts.base.replace(/\/$/, "")}/${app.replace(/^\//, "")}`;
|
|
427
|
-
const entry = await checkStatus(`${root}/
|
|
427
|
+
const entry = await checkStatus(`${root}/fulgurjs-remoteEntry.js`, app, "fulgurjs-remoteEntry.js", {
|
|
428
428
|
expectJs: true,
|
|
429
429
|
expectNoCache: !opts.dev
|
|
430
430
|
});
|
|
@@ -440,7 +440,7 @@ async function runDoctor(opts) {
|
|
|
440
440
|
fix: acao ? void 0 : 'nginx \u5BF9 remoteEntry add_header Access-Control-Allow-Origin "*"'
|
|
441
441
|
});
|
|
442
442
|
}
|
|
443
|
-
const manifestRes = await checkStatus(`${root}/
|
|
443
|
+
const manifestRes = await checkStatus(`${root}/fulgurjs-manifest.json`, app, "fulgurjs-manifest.json", {
|
|
444
444
|
expectNoCache: !opts.dev
|
|
445
445
|
});
|
|
446
446
|
if (manifestRes.check) checks.push(manifestRes.check);
|
|
@@ -454,7 +454,7 @@ async function runDoctor(opts) {
|
|
|
454
454
|
app,
|
|
455
455
|
item: "manifest \u89E3\u6790",
|
|
456
456
|
level: "FAIL",
|
|
457
|
-
symptom: "
|
|
457
|
+
symptom: "fulgurjs-manifest.json \u4E0D\u662F\u5408\u6CD5 JSON",
|
|
458
458
|
cause: "\u4EA7\u7269\u4E0D\u5B8C\u6574\u6216\u88AB\u4E2D\u95F4\u5C42\u6539\u5199",
|
|
459
459
|
fix: "\u91CD\u65B0\u6784\u5EFA\u90E8\u7F72\uFF1B\u786E\u8BA4 nginx \u672A\u5BF9\u8BE5\u8DEF\u5F84\u505A sub/\u62FC\u63A5\u6539\u5199"
|
|
460
460
|
});
|
|
@@ -467,7 +467,7 @@ async function runDoctor(opts) {
|
|
|
467
467
|
htmlBody = html.res?.body ?? "";
|
|
468
468
|
}
|
|
469
469
|
if (opts.dev) {
|
|
470
|
-
const devEntry = await checkStatus(`${root}/@
|
|
470
|
+
const devEntry = await checkStatus(`${root}/@fulgurjs-entry.js`, app, "@fulgurjs-entry.js\uFF08dev \u5BB9\u5668\u5165\u53E3\uFF09", {
|
|
471
471
|
expectJs: true
|
|
472
472
|
});
|
|
473
473
|
if (devEntry.check) checks.push(devEntry.check);
|
|
@@ -549,7 +549,7 @@ async function runDoctor(opts) {
|
|
|
549
549
|
function formatDoctorReport(checks) {
|
|
550
550
|
const lines = [];
|
|
551
551
|
for (const c of checks) {
|
|
552
|
-
const head = `[
|
|
552
|
+
const head = `[fulgurjs:doctor] ${c.level} [${c.app}] ${c.item}`;
|
|
553
553
|
lines.push(c.level === "PASS" ? `${head} \u2014 ${c.symptom}` : `${head}
|
|
554
554
|
\u73B0\u8C61\uFF1A${c.symptom}`);
|
|
555
555
|
if (c.cause) lines.push(` \u6839\u56E0\uFF1A${c.cause}`);
|
|
@@ -558,25 +558,25 @@ function formatDoctorReport(checks) {
|
|
|
558
558
|
const fail = checks.filter((c) => c.level === "FAIL").length;
|
|
559
559
|
const warn = checks.filter((c) => c.level === "WARN").length;
|
|
560
560
|
const pass = checks.filter((c) => c.level === "PASS").length;
|
|
561
|
-
lines.push(`[
|
|
561
|
+
lines.push(`[fulgurjs:doctor] \u6C47\u603B\uFF1A${pass} PASS / ${warn} WARN / ${fail} FAIL`);
|
|
562
562
|
return lines.join("\n");
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
// src/cli.ts
|
|
566
|
-
var HELP = `
|
|
566
|
+
var HELP = `fulgurjs \u2014 Vite Module Federation CLI (@fulgurjs/federation)
|
|
567
567
|
|
|
568
568
|
\u7528\u6CD5\uFF1A
|
|
569
|
-
|
|
570
|
-
|
|
569
|
+
fulgurjs init [--template <path>] [--force] \u751F\u6210\u5E26\u6CE8\u91CA\u7684 fulgurjs.config.ts \u8D77\u6B65\u6A21\u677F
|
|
570
|
+
fulgurjs init --config <path> \u6821\u9A8C\u914D\u7F6E\uFF1B\u8F93\u51FA\u5404\u5E94\u7528 federation() \u7C98\u8D34\u5757\u3001
|
|
571
571
|
NGINX no-cache \u7AD9\u70B9\u6A21\u677F\u4E0E\u63A5\u5165\u6838\u5BF9\u6E05\u5355
|
|
572
|
-
|
|
573
|
-
|
|
572
|
+
fulgurjs doctor --base <URL> --apps <a,b,c> [--dev] [--json] [--chunk-sample N]
|
|
573
|
+
fulgurjs --help
|
|
574
574
|
|
|
575
575
|
\u793A\u4F8B\uFF1A
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
576
|
+
fulgurjs init # \u5F53\u524D\u76EE\u5F55\u5199 fulgurjs.config.ts\uFF08\u5DF2\u5B58\u5728\u5219\u62D2\u7EDD\uFF0C--force \u8986\u76D6\uFF09
|
|
577
|
+
fulgurjs init --config fulgurjs.config.ts # \u6821\u9A8C + \u8F93\u51FA\u6837\u677F
|
|
578
|
+
fulgurjs doctor --base http://your-site --apps app-a,app-b
|
|
579
|
+
fulgurjs doctor --base http://localhost:5173 --apps app-a --dev
|
|
580
580
|
`;
|
|
581
581
|
async function main() {
|
|
582
582
|
const argv = process.argv.slice(2);
|
|
@@ -602,25 +602,25 @@ async function main() {
|
|
|
602
602
|
return 2;
|
|
603
603
|
}
|
|
604
604
|
}
|
|
605
|
-
const target = resolve(argOf("--template") ?? "
|
|
605
|
+
const target = resolve(argOf("--template") ?? "fulgurjs.config.ts");
|
|
606
606
|
const result = await writeConfigTemplate2(target, has("--force"));
|
|
607
607
|
if (result === "exists") {
|
|
608
|
-
console.error(`[
|
|
608
|
+
console.error(`[fulgurjs:init] ${target} \u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6\uFF08--force \u5F3A\u5236\u8986\u76D6\uFF09`);
|
|
609
609
|
return 2;
|
|
610
610
|
}
|
|
611
|
-
console.log(`[
|
|
611
|
+
console.log(`[fulgurjs:init] \u5DF2\u751F\u6210\u8D77\u6B65\u6A21\u677F ${target}
|
|
612
612
|
\u540E\u7EED\u6B65\u9AA4\uFF1A
|
|
613
|
-
1. \u7F16\u8F91
|
|
614
|
-
2. npx
|
|
613
|
+
1. \u7F16\u8F91 fulgurjs.config.ts\uFF1A\u586B\u5165\u4F60\u7684\u5E94\u7528\u76EE\u5F55/\u5BB9\u5668\u540D/\u7AEF\u53E3/base/\u9875\u9762\u8DEF\u7531\u8868/exposes
|
|
614
|
+
2. npx fulgurjs init --config fulgurjs.config.ts # \u6821\u9A8C\u5E76\u8F93\u51FA\u53EF\u7C98\u8D34\u6837\u677F\u4E0E\u6838\u5BF9\u6E05\u5355
|
|
615
615
|
3. \u6309\u6E05\u5355\u628A federation() \u5757\u63A5\u5165\u5404\u5E94\u7528 vite.config.ts\uFF0C\u5B89\u88C5\u4F9D\u8D56
|
|
616
|
-
4. \u90E8\u7F72\u540E\uFF1Anpx
|
|
616
|
+
4. \u90E8\u7F72\u540E\uFF1Anpx fulgurjs doctor --base <URL> --apps <\u5E94\u7528...>`);
|
|
617
617
|
return 0;
|
|
618
618
|
}
|
|
619
619
|
if (cmd === "doctor") {
|
|
620
620
|
const base = argOf("--base");
|
|
621
621
|
const appsRaw = argOf("--apps") ?? "main";
|
|
622
622
|
if (!base) {
|
|
623
|
-
console.error("[
|
|
623
|
+
console.error("[fulgurjs:doctor] \u7F3A\u5C11 --base <URL>\uFF08\u7AD9\u70B9\u6839\u5730\u5740\uFF0C\u5982 http://your-site\uFF09");
|
|
624
624
|
return 2;
|
|
625
625
|
}
|
|
626
626
|
const apps = appsRaw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -644,7 +644,7 @@ ${HELP}`);
|
|
|
644
644
|
main().then(
|
|
645
645
|
(code) => process.exit(code),
|
|
646
646
|
(e) => {
|
|
647
|
-
console.error("[
|
|
647
|
+
console.error("[fulgurjs] \u6267\u884C\u5931\u8D25\uFF1A", e);
|
|
648
648
|
process.exit(2);
|
|
649
649
|
}
|
|
650
650
|
);
|
package/dist/config.cjs
CHANGED
|
@@ -30,15 +30,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/config.ts
|
|
31
31
|
var config_exports = {};
|
|
32
32
|
__export(config_exports, {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
defineFulgurjsConfig: () => defineFulgurjsConfig,
|
|
34
|
+
loadFulgurjsConfig: () => loadFulgurjsConfig
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(config_exports);
|
|
37
37
|
var import_meta = {};
|
|
38
|
-
function
|
|
38
|
+
function defineFulgurjsConfig(config) {
|
|
39
39
|
return config;
|
|
40
40
|
}
|
|
41
|
-
async function
|
|
41
|
+
async function loadFulgurjsConfig(configPath) {
|
|
42
42
|
const { pathToFileURL, fileURLToPath } = await import("url");
|
|
43
43
|
const { createRequire } = await import("module");
|
|
44
44
|
const fs = await import("fs");
|
|
@@ -46,8 +46,8 @@ async function loadFulgurConfig(configPath) {
|
|
|
46
46
|
const path = await import("path");
|
|
47
47
|
const selfDir = path.dirname(fileURLToPath(import_meta.url));
|
|
48
48
|
const selfConfigJs = path.join(selfDir, "config.js");
|
|
49
|
-
const SELF_SPEC = fs.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@
|
|
50
|
-
const rewriteSelfImports = (source) => source.replace(/(['"])@
|
|
49
|
+
const SELF_SPEC = fs.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@fulgurjs-federation-config-unavailable";
|
|
50
|
+
const rewriteSelfImports = (source) => source.replace(/(['"])@fulgurjs\/federation\/config\1/g, (_m, q) => `${q}${SELF_SPEC}${q}`);
|
|
51
51
|
const importConfigs = async (cacheKey) => {
|
|
52
52
|
return await import(`${cacheKey}?t=${Date.now()}`);
|
|
53
53
|
};
|
|
@@ -56,7 +56,7 @@ async function loadFulgurConfig(configPath) {
|
|
|
56
56
|
mod = { default: JSON.parse(fs.readFileSync(configPath, "utf8")) };
|
|
57
57
|
} else {
|
|
58
58
|
const source = rewriteSelfImports(fs.readFileSync(configPath, "utf8"));
|
|
59
|
-
const tmpBase = path.join(os.tmpdir(), `
|
|
59
|
+
const tmpBase = path.join(os.tmpdir(), `fulgurjs-config-${Date.now()}`);
|
|
60
60
|
if (/\.(ts|mts|cts)$/.test(configPath)) {
|
|
61
61
|
try {
|
|
62
62
|
const tmpTs = `${tmpBase}.ts`;
|
|
@@ -88,18 +88,18 @@ async function loadFulgurConfig(configPath) {
|
|
|
88
88
|
const cfg = mod.default;
|
|
89
89
|
if (!cfg?.root) {
|
|
90
90
|
throw new Error(
|
|
91
|
-
`[
|
|
91
|
+
`[fulgurjs:init] \u914D\u7F6E\u7F3A\u5C11 root\uFF08\u5DE5\u7A0B\u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF09
|
|
92
92
|
\u6839\u56E0\uFF1ACLI \u9700\u8981\u77E5\u9053\u5728\u54EA\u4E2A\u5DE5\u7A0B\u4E0A\u505A\u96C6\u6210
|
|
93
|
-
\u4FEE\u6CD5\
|
|
93
|
+
\u4FEE\u6CD5\uFF1Afulgurjs.config.ts \u9876\u5C42\u8865 root: '/abs/path/to/repo'\uFF08\u8D77\u6B65\u6A21\u677F\uFF1Afulgurjs init\uFF09`
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
96
|
if (!Array.isArray(cfg.apps) || cfg.apps.length === 0) {
|
|
97
|
-
throw new Error("[
|
|
97
|
+
throw new Error("[fulgurjs:init] \u914D\u7F6E\u7F3A\u5C11 apps\uFF08\u81F3\u5C11\u4E00\u4E2A\u5BBF\u4E3B\u6216\u8FDC\u7A0B\u5E94\u7528\uFF09");
|
|
98
98
|
}
|
|
99
99
|
for (const app of cfg.apps) {
|
|
100
100
|
if (!app.host && !app.remote) {
|
|
101
101
|
throw new Error(
|
|
102
|
-
`[
|
|
102
|
+
`[fulgurjs:init] \u5E94\u7528 "${app.path}" \u65E2\u65E0 host \u4E5F\u65E0 remote \u89D2\u8272
|
|
103
103
|
\u6839\u56E0\uFF1A\u5E94\u7528\u5FC5\u987B\u81F3\u5C11\u58F0\u660E\u4E00\u4E2A\u89D2\u8272
|
|
104
104
|
\u4FEE\u6CD5\uFF1A\u5BBF\u4E3B\u8865 host: { pages, remotePrefixes, remotes }\uFF0C\u8FDC\u7A0B\u8865 remote: { exposes }`
|
|
105
105
|
);
|
|
@@ -109,6 +109,6 @@ async function loadFulgurConfig(configPath) {
|
|
|
109
109
|
}
|
|
110
110
|
// Annotate the CommonJS export names for ESM import in node:
|
|
111
111
|
0 && (module.exports = {
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
defineFulgurjsConfig,
|
|
113
|
+
loadFulgurjsConfig
|
|
114
114
|
});
|
package/dist/config.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* W1
|
|
2
|
+
* W1 fulgurjs.config.ts:单配置文件驱动的 schema + 加载器(项目无关,决策见排期文档 §4:
|
|
3
3
|
* 主包内置 bin + 单配置文件驱动,可入库可复跑)。
|
|
4
4
|
* init 只消费该配置生成通用样板(见 init.ts);插件运行时(federation())不读取本文件。
|
|
5
5
|
*/
|
|
6
|
-
interface
|
|
6
|
+
interface FulgurjsPageEntry {
|
|
7
7
|
/** 宿主路由路径(参数段用 :xx) */
|
|
8
8
|
route: string;
|
|
9
9
|
/** 路由 name(命名跳转依赖) */
|
|
@@ -13,25 +13,25 @@ interface FulgurPageEntry {
|
|
|
13
13
|
/** 页签标题 */
|
|
14
14
|
title?: string;
|
|
15
15
|
}
|
|
16
|
-
interface
|
|
16
|
+
interface FulgurjsRemoteAddress {
|
|
17
17
|
dev: string;
|
|
18
18
|
prod: string;
|
|
19
19
|
}
|
|
20
|
-
interface
|
|
20
|
+
interface FulgurjsHostConfig {
|
|
21
21
|
/** 页面路由表 */
|
|
22
|
-
pages:
|
|
22
|
+
pages: FulgurjsPageEntry[];
|
|
23
23
|
/** 路由前缀 → 远程名 */
|
|
24
24
|
remotePrefixes: Record<string, string>;
|
|
25
25
|
/** 消费的远程地址(键 = import 前缀;裸 URL,对象形式不支持 name@ 前缀) */
|
|
26
|
-
remotes: Record<string,
|
|
26
|
+
remotes: Record<string, FulgurjsRemoteAddress>;
|
|
27
27
|
}
|
|
28
|
-
interface
|
|
28
|
+
interface FulgurjsRemoteConfig {
|
|
29
29
|
/** exposes:./键 → 源文件(独立页) */
|
|
30
30
|
exposes: Record<string, string>;
|
|
31
31
|
/** 反向消费的远程(双向联邦时;dev 下自身源码参与协商需 devSharedSelf: true) */
|
|
32
|
-
remotes?: Record<string,
|
|
32
|
+
remotes?: Record<string, FulgurjsRemoteAddress>;
|
|
33
33
|
}
|
|
34
|
-
interface
|
|
34
|
+
interface FulgurjsAppConfig {
|
|
35
35
|
/** 相对 root 的应用目录 */
|
|
36
36
|
path: string;
|
|
37
37
|
/** 联邦容器名 */
|
|
@@ -43,37 +43,37 @@ interface FulgurAppConfig {
|
|
|
43
43
|
/** 部署目录名(缺省取 base 去斜杠) */
|
|
44
44
|
deployDir?: string;
|
|
45
45
|
/** 宿主角色 */
|
|
46
|
-
host?:
|
|
46
|
+
host?: FulgurjsHostConfig;
|
|
47
47
|
/** 远程角色 */
|
|
48
|
-
remote?:
|
|
48
|
+
remote?: FulgurjsRemoteConfig;
|
|
49
49
|
/** 该应用的 shared 表(缺省建议 vue/vue-router/pinia singleton,见 init 输出的样板) */
|
|
50
50
|
shared?: Record<string, {
|
|
51
51
|
singleton?: boolean;
|
|
52
52
|
requiredVersion?: string;
|
|
53
53
|
}>;
|
|
54
54
|
}
|
|
55
|
-
interface
|
|
55
|
+
interface FulgurjsDeployConfig {
|
|
56
56
|
/** NGINX 站点根(样板输出用,可选) */
|
|
57
57
|
webRoot?: string;
|
|
58
58
|
/** 监听端口(样板输出用,可选) */
|
|
59
59
|
listen?: number;
|
|
60
60
|
}
|
|
61
|
-
interface
|
|
61
|
+
interface FulgurjsRepoConfig {
|
|
62
62
|
/** 工程根(monorepo 根或单应用仓库根) */
|
|
63
63
|
root: string;
|
|
64
|
-
apps:
|
|
65
|
-
deploy?:
|
|
64
|
+
apps: FulgurjsAppConfig[];
|
|
65
|
+
deploy?: FulgurjsDeployConfig;
|
|
66
66
|
}
|
|
67
|
-
type
|
|
67
|
+
type FulgurjsUserConfig = Partial<FulgurjsRepoConfig>;
|
|
68
68
|
/** 用户配置文件入口:仅做类型收窄(identity),不引入运行时逻辑 */
|
|
69
|
-
declare function
|
|
69
|
+
declare function defineFulgurjsConfig(config: FulgurjsUserConfig): FulgurjsUserConfig;
|
|
70
70
|
/**
|
|
71
|
-
* 加载
|
|
71
|
+
* 加载 fulgurjs.config.ts(或 .js/.json)。
|
|
72
72
|
* - 配置内的 `@fulgurjs/federation/config` 导入被重写为本包 dist/config.js 绝对路径——
|
|
73
73
|
* init 之前工程依赖尚未安装(鸡生蛋),重写后零依赖可加载;
|
|
74
74
|
* - TS 走 Node 原生类型剥离(Node ≥23.6 默认开启;配置文件须用可擦除语法——纯对象无 enum/namespace);
|
|
75
75
|
* 老版本 Node 回退 esbuild 转译(先试配置工程,再试 CLI 自带依赖树)。
|
|
76
76
|
*/
|
|
77
|
-
declare function
|
|
77
|
+
declare function loadFulgurjsConfig(configPath: string): Promise<FulgurjsRepoConfig>;
|
|
78
78
|
|
|
79
|
-
export { type
|
|
79
|
+
export { type FulgurjsAppConfig, type FulgurjsDeployConfig, type FulgurjsHostConfig, type FulgurjsPageEntry, type FulgurjsRemoteAddress, type FulgurjsRemoteConfig, type FulgurjsRepoConfig, type FulgurjsUserConfig, defineFulgurjsConfig, loadFulgurjsConfig };
|
package/dist/config.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* W1
|
|
2
|
+
* W1 fulgurjs.config.ts:单配置文件驱动的 schema + 加载器(项目无关,决策见排期文档 §4:
|
|
3
3
|
* 主包内置 bin + 单配置文件驱动,可入库可复跑)。
|
|
4
4
|
* init 只消费该配置生成通用样板(见 init.ts);插件运行时(federation())不读取本文件。
|
|
5
5
|
*/
|
|
6
|
-
interface
|
|
6
|
+
interface FulgurjsPageEntry {
|
|
7
7
|
/** 宿主路由路径(参数段用 :xx) */
|
|
8
8
|
route: string;
|
|
9
9
|
/** 路由 name(命名跳转依赖) */
|
|
@@ -13,25 +13,25 @@ interface FulgurPageEntry {
|
|
|
13
13
|
/** 页签标题 */
|
|
14
14
|
title?: string;
|
|
15
15
|
}
|
|
16
|
-
interface
|
|
16
|
+
interface FulgurjsRemoteAddress {
|
|
17
17
|
dev: string;
|
|
18
18
|
prod: string;
|
|
19
19
|
}
|
|
20
|
-
interface
|
|
20
|
+
interface FulgurjsHostConfig {
|
|
21
21
|
/** 页面路由表 */
|
|
22
|
-
pages:
|
|
22
|
+
pages: FulgurjsPageEntry[];
|
|
23
23
|
/** 路由前缀 → 远程名 */
|
|
24
24
|
remotePrefixes: Record<string, string>;
|
|
25
25
|
/** 消费的远程地址(键 = import 前缀;裸 URL,对象形式不支持 name@ 前缀) */
|
|
26
|
-
remotes: Record<string,
|
|
26
|
+
remotes: Record<string, FulgurjsRemoteAddress>;
|
|
27
27
|
}
|
|
28
|
-
interface
|
|
28
|
+
interface FulgurjsRemoteConfig {
|
|
29
29
|
/** exposes:./键 → 源文件(独立页) */
|
|
30
30
|
exposes: Record<string, string>;
|
|
31
31
|
/** 反向消费的远程(双向联邦时;dev 下自身源码参与协商需 devSharedSelf: true) */
|
|
32
|
-
remotes?: Record<string,
|
|
32
|
+
remotes?: Record<string, FulgurjsRemoteAddress>;
|
|
33
33
|
}
|
|
34
|
-
interface
|
|
34
|
+
interface FulgurjsAppConfig {
|
|
35
35
|
/** 相对 root 的应用目录 */
|
|
36
36
|
path: string;
|
|
37
37
|
/** 联邦容器名 */
|
|
@@ -43,37 +43,37 @@ interface FulgurAppConfig {
|
|
|
43
43
|
/** 部署目录名(缺省取 base 去斜杠) */
|
|
44
44
|
deployDir?: string;
|
|
45
45
|
/** 宿主角色 */
|
|
46
|
-
host?:
|
|
46
|
+
host?: FulgurjsHostConfig;
|
|
47
47
|
/** 远程角色 */
|
|
48
|
-
remote?:
|
|
48
|
+
remote?: FulgurjsRemoteConfig;
|
|
49
49
|
/** 该应用的 shared 表(缺省建议 vue/vue-router/pinia singleton,见 init 输出的样板) */
|
|
50
50
|
shared?: Record<string, {
|
|
51
51
|
singleton?: boolean;
|
|
52
52
|
requiredVersion?: string;
|
|
53
53
|
}>;
|
|
54
54
|
}
|
|
55
|
-
interface
|
|
55
|
+
interface FulgurjsDeployConfig {
|
|
56
56
|
/** NGINX 站点根(样板输出用,可选) */
|
|
57
57
|
webRoot?: string;
|
|
58
58
|
/** 监听端口(样板输出用,可选) */
|
|
59
59
|
listen?: number;
|
|
60
60
|
}
|
|
61
|
-
interface
|
|
61
|
+
interface FulgurjsRepoConfig {
|
|
62
62
|
/** 工程根(monorepo 根或单应用仓库根) */
|
|
63
63
|
root: string;
|
|
64
|
-
apps:
|
|
65
|
-
deploy?:
|
|
64
|
+
apps: FulgurjsAppConfig[];
|
|
65
|
+
deploy?: FulgurjsDeployConfig;
|
|
66
66
|
}
|
|
67
|
-
type
|
|
67
|
+
type FulgurjsUserConfig = Partial<FulgurjsRepoConfig>;
|
|
68
68
|
/** 用户配置文件入口:仅做类型收窄(identity),不引入运行时逻辑 */
|
|
69
|
-
declare function
|
|
69
|
+
declare function defineFulgurjsConfig(config: FulgurjsUserConfig): FulgurjsUserConfig;
|
|
70
70
|
/**
|
|
71
|
-
* 加载
|
|
71
|
+
* 加载 fulgurjs.config.ts(或 .js/.json)。
|
|
72
72
|
* - 配置内的 `@fulgurjs/federation/config` 导入被重写为本包 dist/config.js 绝对路径——
|
|
73
73
|
* init 之前工程依赖尚未安装(鸡生蛋),重写后零依赖可加载;
|
|
74
74
|
* - TS 走 Node 原生类型剥离(Node ≥23.6 默认开启;配置文件须用可擦除语法——纯对象无 enum/namespace);
|
|
75
75
|
* 老版本 Node 回退 esbuild 转译(先试配置工程,再试 CLI 自带依赖树)。
|
|
76
76
|
*/
|
|
77
|
-
declare function
|
|
77
|
+
declare function loadFulgurjsConfig(configPath: string): Promise<FulgurjsRepoConfig>;
|
|
78
78
|
|
|
79
|
-
export { type
|
|
79
|
+
export { type FulgurjsAppConfig, type FulgurjsDeployConfig, type FulgurjsHostConfig, type FulgurjsPageEntry, type FulgurjsRemoteAddress, type FulgurjsRemoteConfig, type FulgurjsRepoConfig, type FulgurjsUserConfig, defineFulgurjsConfig, loadFulgurjsConfig };
|
package/dist/config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
-
function
|
|
2
|
+
function defineFulgurjsConfig(config) {
|
|
3
3
|
return config;
|
|
4
4
|
}
|
|
5
|
-
async function
|
|
5
|
+
async function loadFulgurjsConfig(configPath) {
|
|
6
6
|
const { pathToFileURL, fileURLToPath } = await import("url");
|
|
7
7
|
const { createRequire } = await import("module");
|
|
8
8
|
const fs = await import("fs");
|
|
@@ -10,8 +10,8 @@ async function loadFulgurConfig(configPath) {
|
|
|
10
10
|
const path = await import("path");
|
|
11
11
|
const selfDir = path.dirname(fileURLToPath(import.meta.url));
|
|
12
12
|
const selfConfigJs = path.join(selfDir, "config.js");
|
|
13
|
-
const SELF_SPEC = fs.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@
|
|
14
|
-
const rewriteSelfImports = (source) => source.replace(/(['"])@
|
|
13
|
+
const SELF_SPEC = fs.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@fulgurjs-federation-config-unavailable";
|
|
14
|
+
const rewriteSelfImports = (source) => source.replace(/(['"])@fulgurjs\/federation\/config\1/g, (_m, q) => `${q}${SELF_SPEC}${q}`);
|
|
15
15
|
const importConfigs = async (cacheKey) => {
|
|
16
16
|
return await import(`${cacheKey}?t=${Date.now()}`);
|
|
17
17
|
};
|
|
@@ -20,7 +20,7 @@ async function loadFulgurConfig(configPath) {
|
|
|
20
20
|
mod = { default: JSON.parse(fs.readFileSync(configPath, "utf8")) };
|
|
21
21
|
} else {
|
|
22
22
|
const source = rewriteSelfImports(fs.readFileSync(configPath, "utf8"));
|
|
23
|
-
const tmpBase = path.join(os.tmpdir(), `
|
|
23
|
+
const tmpBase = path.join(os.tmpdir(), `fulgurjs-config-${Date.now()}`);
|
|
24
24
|
if (/\.(ts|mts|cts)$/.test(configPath)) {
|
|
25
25
|
try {
|
|
26
26
|
const tmpTs = `${tmpBase}.ts`;
|
|
@@ -52,18 +52,18 @@ async function loadFulgurConfig(configPath) {
|
|
|
52
52
|
const cfg = mod.default;
|
|
53
53
|
if (!cfg?.root) {
|
|
54
54
|
throw new Error(
|
|
55
|
-
`[
|
|
55
|
+
`[fulgurjs:init] \u914D\u7F6E\u7F3A\u5C11 root\uFF08\u5DE5\u7A0B\u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF09
|
|
56
56
|
\u6839\u56E0\uFF1ACLI \u9700\u8981\u77E5\u9053\u5728\u54EA\u4E2A\u5DE5\u7A0B\u4E0A\u505A\u96C6\u6210
|
|
57
|
-
\u4FEE\u6CD5\
|
|
57
|
+
\u4FEE\u6CD5\uFF1Afulgurjs.config.ts \u9876\u5C42\u8865 root: '/abs/path/to/repo'\uFF08\u8D77\u6B65\u6A21\u677F\uFF1Afulgurjs init\uFF09`
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
if (!Array.isArray(cfg.apps) || cfg.apps.length === 0) {
|
|
61
|
-
throw new Error("[
|
|
61
|
+
throw new Error("[fulgurjs:init] \u914D\u7F6E\u7F3A\u5C11 apps\uFF08\u81F3\u5C11\u4E00\u4E2A\u5BBF\u4E3B\u6216\u8FDC\u7A0B\u5E94\u7528\uFF09");
|
|
62
62
|
}
|
|
63
63
|
for (const app of cfg.apps) {
|
|
64
64
|
if (!app.host && !app.remote) {
|
|
65
65
|
throw new Error(
|
|
66
|
-
`[
|
|
66
|
+
`[fulgurjs:init] \u5E94\u7528 "${app.path}" \u65E2\u65E0 host \u4E5F\u65E0 remote \u89D2\u8272
|
|
67
67
|
\u6839\u56E0\uFF1A\u5E94\u7528\u5FC5\u987B\u81F3\u5C11\u58F0\u660E\u4E00\u4E2A\u89D2\u8272
|
|
68
68
|
\u4FEE\u6CD5\uFF1A\u5BBF\u4E3B\u8865 host: { pages, remotePrefixes, remotes }\uFF0C\u8FDC\u7A0B\u8865 remote: { exposes }`
|
|
69
69
|
);
|
|
@@ -72,6 +72,6 @@ async function loadFulgurConfig(configPath) {
|
|
|
72
72
|
return cfg;
|
|
73
73
|
}
|
|
74
74
|
export {
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
defineFulgurjsConfig,
|
|
76
|
+
loadFulgurjsConfig
|
|
77
77
|
};
|