@fulgurjs/federation 5.9.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/README.en.md +57 -416
- package/README.md +56 -446
- package/dist/bridge-app-vue.d.cts +1 -1
- package/dist/bridge-app-vue.d.ts +1 -1
- package/dist/bridge-core.cjs +1 -1
- package/dist/bridge-core.js +2 -2
- package/dist/bridge-errors.cjs +1 -1
- package/dist/bridge-errors.js +1 -1
- package/dist/bridge-host-react.cjs +1 -1
- package/dist/bridge-host-react.js +3 -3
- package/dist/bridge-host-vue.cjs +1 -1
- package/dist/bridge-host-vue.js +3 -3
- package/dist/bridge-router-react.d.ts +4 -2
- package/dist/bridge-router-react.js +95 -9
- package/dist/bridge-router-vue.d.ts +24 -5
- package/dist/bridge-router-vue.js +4 -5
- package/dist/{chunk-YKIFZIBH.js → chunk-77JZ6U6V.js} +1 -1
- package/dist/{chunk-Q6V5O5Y6.js → chunk-ENT3BOTX.js} +1 -1
- package/dist/{chunk-WRJG2YG6.js → chunk-ZAYNS7YQ.js} +1 -1
- package/dist/cli.js +460 -109
- package/dist/index.cjs +25 -38
- package/dist/index.js +25 -38
- package/dist/react.d.ts +194 -101
- package/dist/react.js +4 -0
- package/dist/runtime-entry.d.ts +9 -174
- package/dist/runtime-entry.js +0 -1
- package/dist/runtime.js +1 -1
- package/dist/vue-adapter.cjs +5 -1
- package/dist/vue-adapter.js +5 -1
- package/dist/vue.d.ts +576 -0
- package/dist/vue.js +8 -0
- package/docs/en/migration.md +210 -0
- package/docs/en/reference/api.md +534 -0
- package/docs/en/reference/errors.md +86 -0
- package/docs/{P5-vite7-8 → maintainers/P5-vite7-8}/345/205/274/345/256/271/347/237/251/351/230/265.md +7 -9
- package/docs/{webpack-mf- → maintainers/webpack-mf-}/345/257/271/347/205/247/344/270/216/347/274/272/345/217/243.md +10 -10
- package/docs/maintainers//346/262/231/347/256/261/350/276/271/347/225/214/345/256/241/350/256/241.md +43 -0
- package/docs/zh/migration.md +210 -0
- package/docs/zh/reference/api.md +533 -0
- package/docs/zh/reference/errors.md +86 -0
- package/examples/templates/README.md +1 -1
- package/examples/templates/react-host-vue-remote/pnpm-lock.yaml +7 -7
- package/examples/templates/react-host-vue-remote/pnpm-workspace.yaml +1 -1
- package/examples/templates/react-host-vue-remote/react-host/README.md +2 -2
- package/examples/templates/react-host-vue-remote/react-host/package.json +1 -1
- package/examples/templates/react-host-vue-remote/react-host/src/main.tsx +2 -2
- package/examples/templates/react-host-vue-remote/scripts/dev.config.json +11 -2
- package/examples/templates/react-host-vue-remote/vue-remote/package.json +1 -1
- package/examples/templates/react-host-vue-remote/vue-remote/src/bridge.ts +1 -1
- package/examples/templates/react-react/host/package.json +1 -1
- package/examples/templates/react-react/pnpm-lock.yaml +7 -7
- package/examples/templates/react-react/pnpm-workspace.yaml +1 -1
- package/examples/templates/react-react/remote/package.json +1 -1
- package/examples/templates/react-react/scripts/dev.config.json +11 -2
- package/examples/templates/showcase/README.md +6 -6
- package/examples/templates/showcase/pnpm-lock.yaml +11 -11
- package/examples/templates/showcase/pnpm-workspace.yaml +1 -1
- package/examples/templates/showcase/react-host/package.json +1 -1
- package/examples/templates/showcase/react-host/src/pages/BridgeVuePage.tsx +1 -1
- package/examples/templates/showcase/react-host/src/routing.ts +1 -1
- package/examples/templates/showcase/react-remote/package.json +1 -1
- package/examples/templates/showcase/react-remote/src/bridge.tsx +1 -1
- package/examples/templates/showcase/scripts/dev.config.json +22 -4
- package/examples/templates/showcase/vue-host/package.json +1 -1
- package/examples/templates/showcase/vue-host/src/pages/BridgeReactPage.vue +1 -1
- package/examples/templates/showcase/vue-host/src/routing.ts +3 -13
- package/examples/templates/showcase/vue-remote/package.json +1 -1
- package/examples/templates/showcase/vue-remote/src/bridge.ts +2 -2
- package/examples/templates/vue-host-react-remote/pnpm-lock.yaml +7 -7
- package/examples/templates/vue-host-react-remote/pnpm-workspace.yaml +1 -1
- package/examples/templates/vue-host-react-remote/react-remote/package.json +1 -1
- package/examples/templates/vue-host-react-remote/scripts/dev.config.json +11 -2
- package/examples/templates/vue-host-react-remote/vue-host/README.md +2 -2
- package/examples/templates/vue-host-react-remote/vue-host/package.json +1 -1
- package/examples/templates/vue-host-react-remote/vue-host/src/App.vue +2 -2
- package/examples/templates/vue-vue/host/package.json +1 -1
- package/examples/templates/vue-vue/host/src/main.ts +28 -21
- package/examples/templates/vue-vue/host/src/pages/HomePage.vue +1 -1
- package/examples/templates/vue-vue/pnpm-lock.yaml +7 -7
- package/examples/templates/vue-vue/pnpm-workspace.yaml +1 -1
- package/examples/templates/vue-vue/remote/package.json +1 -1
- package/examples/templates/vue-vue/scripts/dev.config.json +11 -2
- package/package.json +24 -37
- package/dist/bridge-core-D37VanBl.d.ts +0 -99
- package/dist/bridge-host-react-CGymCzD2.d.ts +0 -35
- package/dist/bridge-host-vue-B3GHaQAC.d.ts +0 -32
- package/dist/bridge-react.d.ts +0 -14
- package/dist/bridge-react.js +0 -3
- package/dist/bridge-vue.d.ts +0 -8
- package/dist/bridge-vue.js +0 -3
- package/dist/bridge.d.ts +0 -18
- package/dist/bridge.js +0 -5
- package/dist/chunk-GLASM5EX.js +0 -1730
- package/dist/chunk-V6EASSCR.js +0 -249
- package/dist/chunk-X34EJB4H.js +0 -207
- package/docs/API.en.md +0 -339
- package/docs/API.md +0 -914
- package/docs//346/262/231/347/256/261/350/276/271/347/225/214/345/256/241/350/256/241.md +0 -45
- package/docs//350/277/201/347/247/273/346/214/207/345/215/227.md +0 -179
package/dist/cli.js
CHANGED
|
@@ -215,18 +215,18 @@ function validateHostPages(value) {
|
|
|
215
215
|
}
|
|
216
216
|
return hp;
|
|
217
217
|
}
|
|
218
|
-
function validatePathsInsideApp(options, appRoot,
|
|
218
|
+
function validatePathsInsideApp(options, appRoot, fs5, path4) {
|
|
219
219
|
const checkModule = (field, value) => {
|
|
220
220
|
if (typeof value !== "string" || value.trim() === "") return;
|
|
221
|
-
if (/^(https?:)?\/\//.test(value) ||
|
|
221
|
+
if (/^(https?:)?\/\//.test(value) || path4.isAbsolute(value)) {
|
|
222
222
|
appConfigError(
|
|
223
223
|
`${field} "${value}" \u4E0D\u662F\u672C\u9879\u76EE\u5185\u7684\u6A21\u5757\u8DEF\u5F84`,
|
|
224
224
|
"exposes/setup \u7684\u503C\u662F\u76F8\u5BF9\u672C\u5E94\u7528\u6839\u76EE\u5F55\u7684\u6E90\u6587\u4EF6\u8DEF\u5F84\uFF08URL/\u7EDD\u5BF9\u8DEF\u5F84\u65E0\u6CD5\u5728\u72EC\u7ACB\u4ED3\u5E93\u95F4\u79FB\u690D\uFF09",
|
|
225
225
|
`\u6539\u4E3A\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5982 './src/views/Home.vue'\uFF08\u914D\u7F6E\u6587\u4EF6\u76EE\u5F55 = \u5E94\u7528\u6839 ${appRoot}\uFF09`
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
|
-
const abs =
|
|
229
|
-
if (!
|
|
228
|
+
const abs = path4.resolve(appRoot, value);
|
|
229
|
+
if (!fs5.existsSync(abs)) {
|
|
230
230
|
appConfigError(
|
|
231
231
|
`${field} \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${value}`,
|
|
232
232
|
`\u6309\u5E94\u7528\u6839 ${appRoot} \u89E3\u6790\u540E\u672A\u627E\u5230\u8BE5\u6587\u4EF6`,
|
|
@@ -295,11 +295,11 @@ function resolveEsbuild(configPath) {
|
|
|
295
295
|
);
|
|
296
296
|
}
|
|
297
297
|
async function loadAppConfig(configPath) {
|
|
298
|
-
const
|
|
298
|
+
const fs5 = await import("node:fs");
|
|
299
299
|
const os = await import("node:os");
|
|
300
|
-
const
|
|
301
|
-
const abs =
|
|
302
|
-
if (!
|
|
300
|
+
const path4 = await import("node:path");
|
|
301
|
+
const abs = path4.resolve(configPath);
|
|
302
|
+
if (!fs5.existsSync(abs)) {
|
|
303
303
|
appConfigError(
|
|
304
304
|
`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${abs}`,
|
|
305
305
|
"--config \u6307\u5411\u7684\u8DEF\u5F84\u5728\u672C\u673A\u4E0D\u5B58\u5728\uFF08\u76F8\u5BF9\u8DEF\u5F84\u4EE5 CLI \u8FDB\u7A0B cwd \u89E3\u6790\uFF09",
|
|
@@ -307,11 +307,11 @@ async function loadAppConfig(configPath) {
|
|
|
307
307
|
);
|
|
308
308
|
}
|
|
309
309
|
if (abs.endsWith(".json")) {
|
|
310
|
-
const parsed = JSON.parse(
|
|
310
|
+
const parsed = JSON.parse(fs5.readFileSync(abs, "utf8"));
|
|
311
311
|
if (isAggregateShape(parsed)) aggregateMigrationError();
|
|
312
|
-
return finishAppShape(parsed, {}, abs,
|
|
312
|
+
return finishAppShape(parsed, {}, abs, path4.dirname(abs), fs5, path4);
|
|
313
313
|
}
|
|
314
|
-
const rawSource =
|
|
314
|
+
const rawSource = fs5.readFileSync(abs, "utf8");
|
|
315
315
|
if (/@fulgurjs\/federation\/config/.test(rawSource)) {
|
|
316
316
|
appConfigError(
|
|
317
317
|
`\u914D\u7F6E\u5BFC\u5165\u4E86\u5DF2\u5220\u9664\u7684\u5B50\u8DEF\u5F84 "@fulgurjs/federation/config"`,
|
|
@@ -342,21 +342,21 @@ async function loadAppConfig(configPath) {
|
|
|
342
342
|
plugins: [selfRedirect],
|
|
343
343
|
logLevel: "silent"
|
|
344
344
|
});
|
|
345
|
-
const tmpDir =
|
|
345
|
+
const tmpDir = fs5.mkdtempSync(path4.join(os.tmpdir(), "fulgurjs-appcfg-"));
|
|
346
346
|
try {
|
|
347
|
-
const bundleFile =
|
|
348
|
-
|
|
347
|
+
const bundleFile = path4.join(tmpDir, "fulgurjs.config.bundle.mjs");
|
|
348
|
+
fs5.writeFileSync(bundleFile, out.outputFiles[0].text);
|
|
349
349
|
const mod = await import(
|
|
350
350
|
/* @vite-ignore */
|
|
351
351
|
`${pathToFileURL(bundleFile).href}?t=${Date.now()}`
|
|
352
352
|
);
|
|
353
353
|
if (isAggregateShape(mod.default)) aggregateMigrationError();
|
|
354
|
-
return finishAppShape(mod.default, { hostPages: mod.hostPages }, abs,
|
|
354
|
+
return finishAppShape(mod.default, { hostPages: mod.hostPages }, abs, path4.dirname(abs), fs5, path4);
|
|
355
355
|
} finally {
|
|
356
|
-
|
|
356
|
+
fs5.rmSync(tmpDir, { recursive: true, force: true });
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
|
-
function finishAppShape(def, named, configPath, appRoot,
|
|
359
|
+
function finishAppShape(def, named, configPath, appRoot, fs5, path4) {
|
|
360
360
|
if (def === void 0 || def === null) {
|
|
361
361
|
appConfigError(
|
|
362
362
|
"fulgurjs.config.ts \u6CA1\u6709\u53EF\u7528\u7684\u9ED8\u8BA4\u5BFC\u51FA",
|
|
@@ -369,7 +369,7 @@ function finishAppShape(def, named, configPath, appRoot, fs4, path3) {
|
|
|
369
369
|
}
|
|
370
370
|
const options = def;
|
|
371
371
|
validateAppOptions(options);
|
|
372
|
-
validatePathsInsideApp(options, appRoot,
|
|
372
|
+
validatePathsInsideApp(options, appRoot, fs5, path4);
|
|
373
373
|
const hostPages = named.hostPages !== void 0 ? validateHostPages(named.hostPages) : void 0;
|
|
374
374
|
return {
|
|
375
375
|
kind: "app",
|
|
@@ -396,18 +396,82 @@ var init_app_config = __esm({
|
|
|
396
396
|
// src/init.ts
|
|
397
397
|
var init_exports = {};
|
|
398
398
|
__export(init_exports, {
|
|
399
|
+
COMMON_CHECKLIST: () => COMMON_CHECKLIST,
|
|
399
400
|
STARTER_CONFIG: () => STARTER_CONFIG,
|
|
401
|
+
checklistFor: () => checklistFor,
|
|
402
|
+
detectFrameworkFromPackageJson: () => detectFrameworkFromPackageJson,
|
|
400
403
|
inspectConfig: () => inspectConfig,
|
|
404
|
+
starterConfigFor: () => starterConfigFor,
|
|
401
405
|
writeConfigTemplate: () => writeConfigTemplate
|
|
402
406
|
});
|
|
403
407
|
import fs from "node:fs";
|
|
404
408
|
import path from "node:path";
|
|
405
|
-
|
|
409
|
+
function detectFrameworkFromPackageJson(pkg) {
|
|
410
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
411
|
+
const hasVue = "vue" in deps;
|
|
412
|
+
const hasReact = "react" in deps;
|
|
413
|
+
if (hasVue && !hasReact) return "vue";
|
|
414
|
+
if (hasReact && !hasVue) return "react";
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
function sharedExample(framework) {
|
|
418
|
+
if (framework === "vue") {
|
|
419
|
+
return ` // \u8DE8\u5E94\u7528\u5171\u4EAB\u7684\u5E93 singleton: true\uFF08\u5168\u5C40\u54CD\u5E94\u6027/\u8DEF\u7531/store \u6CE8\u5165\u8981\u6C42\u540C\u5B9E\u4F8B\uFF09\u3002
|
|
420
|
+
// \u53EA\u5217\u9879\u76EE\u5B9E\u9645\u5B89\u88C5\u4E14\u8981\u8DE8\u5E94\u7528\u5171\u4EAB\u7684\u5E93\uFF1BrequiredVersion \u6309\u9879\u76EE\u5B9E\u9645\u7248\u672C\u6536\u655B\uFF08\u53EF\u7701\u7565\uFF09\u3002
|
|
421
|
+
shared: {
|
|
422
|
+
vue: { singleton: true },
|
|
423
|
+
},`;
|
|
424
|
+
}
|
|
425
|
+
return ` // \u8DE8\u5E94\u7528\u5171\u4EAB\u7684\u5E93 singleton: true\uFF08Hooks \u72B6\u6001/renderer \u8981\u6C42\u540C\u5B9E\u4F8B\uFF09\u3002
|
|
426
|
+
// \u53EA\u5217\u9879\u76EE\u5B9E\u9645\u5B89\u88C5\u4E14\u8981\u8DE8\u5E94\u7528\u5171\u4EAB\u7684\u5E93\uFF1BrequiredVersion \u6309\u9879\u76EE\u5B9E\u9645\u7248\u672C\u6536\u655B\uFF08\u53EF\u7701\u7565\uFF09\u3002
|
|
427
|
+
// react-dom \u4E5F\u6309\u9700\u5171\u4EAB\uFF08\u8FDC\u7A0B\u6E32\u67D3\u8FDB\u5BBF\u4E3B DOM \u65F6\u5FC5\u987B\u540C renderer\uFF09\u3002
|
|
428
|
+
shared: {
|
|
429
|
+
react: { singleton: true },
|
|
430
|
+
'react-dom': { singleton: true },
|
|
431
|
+
},`;
|
|
432
|
+
}
|
|
433
|
+
function starterConfigFor(scenario) {
|
|
434
|
+
const { framework, role } = scenario;
|
|
435
|
+
const wantRemotes = role === "consumer" || role === "dual";
|
|
436
|
+
const wantExposes = role === "provider" || role === "dual";
|
|
437
|
+
const lines = [];
|
|
438
|
+
lines.push(`// fulgurjs.config.ts \u2014\u2014 @fulgurjs/federation \u5355\u9879\u76EE\u63A5\u5165\u914D\u7F6E\uFF08\u4E00\u9879\u76EE\u4E00\u4EFD\uFF0C\u53EF\u5165\u5E93\u3001\u53EF\u590D\u8DD1\uFF09`);
|
|
439
|
+
lines.push(`//`);
|
|
440
|
+
lines.push(`// Vite \u63A5\u5165\uFF08\u672C\u9879\u76EE vite.config.ts \u53EA\u9700\u4E24\u884C\u8054\u90A6\u76F8\u5173\u4EE3\u7801\uFF09\uFF1A`);
|
|
441
|
+
lines.push(`// import federation from '@fulgurjs/federation'`);
|
|
442
|
+
lines.push(`// import fulgurjsConfig from './fulgurjs.config'`);
|
|
443
|
+
lines.push(`// // plugins: [ ...\u539F\u6709\u63D2\u4EF6, federation(fulgurjsConfig) ]`);
|
|
444
|
+
lines.push(`//`);
|
|
445
|
+
lines.push(`// CLI\uFF08\u7EAF\u672C\u5730\uFF0C\u65E0\u7F51\u7EDC\uFF09\uFF1A`);
|
|
446
|
+
lines.push(`// npx fulgurjs explain # \u89E3\u91CA\u672C\u5E94\u7528\u6709\u6548\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE`);
|
|
447
|
+
lines.push(`// npx fulgurjs check-pages # \u9010\u9875\u63A5\u5165\u7684\u5BBF\u4E3B\uFF1A\u9875\u9762\u8868 \u2194 \u8FDC\u7A0B manifest \u5951\u7EA6\u6838\u5BF9`);
|
|
448
|
+
lines.push(`// npx fulgurjs doctor --base http://<\u7AD9\u70B9> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55> # \u90E8\u7F72\u4F53\u68C0`);
|
|
449
|
+
lines.push(`import type { FederationOptions } from '@fulgurjs/federation'`);
|
|
450
|
+
lines.push("");
|
|
451
|
+
lines.push("export default {");
|
|
452
|
+
lines.push(" // \u8054\u90A6\u5BB9\u5668\u540D\uFF08\u8FDC\u7A0B\u5F15\u7528\u5B83\u65F6\u7528\u8FD9\u4E2A\u540D\uFF1B\u540C\u4E00\u9875\u9762\u5185\u552F\u4E00\uFF09");
|
|
453
|
+
lines.push(" name: 'my-app',");
|
|
454
|
+
if (wantExposes) lines.push(EXPOSES_EXAMPLE[framework]);
|
|
455
|
+
if (wantRemotes) lines.push(REMOTES_EXAMPLE);
|
|
456
|
+
lines.push(" // \u53EF\u9009\uFF1A\u8FDC\u7A0B\u9700\u8981\u542F\u52A8\u671F\u521D\u59CB\u5316\uFF08\u5168\u5C40\u6837\u5F0F/\u7EC4\u4EF6/locale\uFF09\u65F6\u58F0\u660E\u5165\u53E3\u6587\u4EF6\u2014\u2014");
|
|
457
|
+
lines.push(" // \u9ED8\u8BA4\u5BFC\u51FA setup(context) \u5E94\u7528\u7EA7\u6267\u884C\u4E00\u6B21\uFF1B\u53EF\u9009\u5177\u540D\u5BFC\u51FA onSession(context)");
|
|
458
|
+
lines.push(" // \u6309\u5BBF\u4E3B sessionKey \u53BB\u91CD\u6267\u884C\u3002\u7F3A\u7701 = \u65E0\u521D\u59CB\u5316\u884C\u4E3A\uFF08\u666E\u901A expose \u8BED\u4E49\u4E0D\u53D8\uFF09");
|
|
459
|
+
lines.push(" // setup: './src/fulgurjs/setup.ts',");
|
|
460
|
+
lines.push(sharedExample(framework));
|
|
461
|
+
lines.push(`} satisfies FederationOptions`);
|
|
462
|
+
if (role === "consumer" || role === "dual") {
|
|
463
|
+
lines.push("");
|
|
464
|
+
lines.push(HOST_PAGES_COMMENT);
|
|
465
|
+
}
|
|
466
|
+
lines.push("");
|
|
467
|
+
return lines.join("\n");
|
|
468
|
+
}
|
|
469
|
+
async function writeConfigTemplate(target, force = false, scenario = { framework: "vue", role: "dual" }) {
|
|
406
470
|
if (fs.existsSync(target) && !force) {
|
|
407
471
|
return "exists";
|
|
408
472
|
}
|
|
409
473
|
fs.mkdirSync(path.dirname(path.resolve(target)), { recursive: true });
|
|
410
|
-
fs.writeFileSync(path.resolve(target),
|
|
474
|
+
fs.writeFileSync(path.resolve(target), starterConfigFor(scenario));
|
|
411
475
|
return "written";
|
|
412
476
|
}
|
|
413
477
|
function viteSnippetForAppMode(appRoot) {
|
|
@@ -422,6 +486,42 @@ export default defineConfig({
|
|
|
422
486
|
],
|
|
423
487
|
})`;
|
|
424
488
|
}
|
|
489
|
+
function checklistFor(scenario) {
|
|
490
|
+
const { framework, role } = scenario;
|
|
491
|
+
const out = [];
|
|
492
|
+
const provide = role === "provider" || role === "dual";
|
|
493
|
+
const consume = role === "consumer" || role === "dual";
|
|
494
|
+
out.push("1. \u5B89\u88C5\u4F9D\u8D56\uFF1Anpm/pnpm add @fulgurjs/federation");
|
|
495
|
+
if (provide) {
|
|
496
|
+
out.push("2. expose \u76EE\u6807\u6309\u7528\u9014\u5206\u7C7B\uFF1A\u666E\u901A\u7EC4\u4EF6/\u51FD\u6570\u6A21\u5757\u53EF\u76F4\u63A5 expose\uFF08\u4F7F\u7528\u65B9 remoteComponent/loadRemote \u6D88\u8D39\uFF09\uFF1B");
|
|
497
|
+
out.push(" \u4F5C\u4E3A\u300C\u9875\u9762\u300D\u63A5\u5165\u5BBF\u4E3B\u9875\u9762\u8DEF\u7531\u8868\u65F6\u624D\u8981\u6C42\u72EC\u7ACB\u9875\uFF08\u9875\u9762\u4ECE\u8DEF\u7531\u53D6\u53C2\uFF09\uFF1B\u7EC4\u4EF6\u5FC5\u586B props \u7ED9\u9ED8\u8BA4\u503C\uFF08BLD-003\uFF09");
|
|
498
|
+
}
|
|
499
|
+
if (consume) {
|
|
500
|
+
out.push("3. \u6D88\u8D39\u65B9\u5F0F\u6309\u9700\u9009\u62E9\uFF1A\u666E\u901A\u7EC4\u4EF6/\u6A21\u5757\u7528 remoteComponent/loadRemote\uFF08\u4E0D\u9700\u8981\u9875\u9762\u8868\u3001\u4E0D\u9700\u8981\u6865\u63A5\u914D\u7F6E\uFF09\uFF1B");
|
|
501
|
+
out.push(" \u5B8C\u6574\u5B50\u5E94\u7528\uFF08\u81EA\u5E26 Router/store\uFF09\u7528\u6865\u63A5 createVueBridgeApp/createReactBridgeApp\u2014\u2014\u5BBF\u4E3B\u53EA\u914D\u6302\u8F7D\u524D\u7F00\u4E0E\u5165\u53E3\uFF0C");
|
|
502
|
+
out.push(" \u5B50\u5E94\u7528\u4FDD\u7559\u81EA\u5DF1\u7684 Router \u4E0E\u4E1A\u52A1\u83DC\u5355\uFF0C\u4E0D\u9010\u9875\u767B\u8BB0\u5185\u90E8\u9875\u9762");
|
|
503
|
+
}
|
|
504
|
+
out.push("4. shared \u91CC\u53EA\u5217\u300C\u9879\u76EE\u5B9E\u9645\u5B89\u88C5\u4E14\u8DE8\u5E94\u7528\u5171\u4EAB\u300D\u7684\u5E93\uFF0C\u8DE8\u5E94\u7528\u540C\u5B9E\u4F8B\u7684\uFF08vue/react/react-dom/router/store\uFF09\u914D singleton: true\uFF1B");
|
|
505
|
+
out.push(" \u72EC\u7ACB Router/store \u7684\u5B8C\u6574\u5B50\u5E94\u7528\u9694\u79BB\u8BBE\u8BA1\u662F\u5408\u6CD5\u7684\u2014\u2014\u4E0D\u662F\u6240\u6709\u5171\u4EAB\u9879\u90FD\u5FC5\u987B singleton");
|
|
506
|
+
if (consume) {
|
|
507
|
+
out.push("5. \u8FDC\u7A0B\u9700\u8981\u542F\u52A8\u671F\u521D\u59CB\u5316\uFF08\u5168\u5C40\u7EC4\u4EF6/\u6837\u5F0F/locale \u7B49\uFF09\u65F6\uFF0C\u5728 fulgurjs.config.ts \u7684 setup \u58F0\u660E\u5165\u53E3\u6587\u4EF6\uFF1A");
|
|
508
|
+
out.push(" \u9ED8\u8BA4\u5BFC\u51FA setup(context) \u5E94\u7528\u7EA7\u6267\u884C\u4E00\u6B21\uFF08\u5BB9\u5668\u9996\u6B21\u88AB\u52A0\u8F7D\u4E1A\u52A1\u6A21\u5757\u524D\uFF09\uFF1B\u53EF\u9009\u5177\u540D\u5BFC\u51FA onSession(context)");
|
|
509
|
+
out.push(" \u6309\u5BBF\u4E3B sessionKey \u53BB\u91CD\u6267\u884C\uFF08\u6362\u8D26\u53F7/\u91CD\u767B\u81EA\u52A8\u91CD\u8DD1\uFF09\u3002\u8DE8\u5E94\u7528\u4F20\u503C\u8D70 context \u51FD\u6570\uFF1A\u5BBF\u4E3B provideAppContext \u5199\u5165");
|
|
510
|
+
out.push(" \uFF08\u9000\u51FA\u65F6 clearAppContext \u6E05\u7406\uFF09\uFF0C\u8FDC\u7A0B setup/onSession \u7528 getAppContext / requireAppContext \u6D88\u8D39");
|
|
511
|
+
}
|
|
512
|
+
out.push(APP_ENTRY_NOTE[framework]);
|
|
513
|
+
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');
|
|
514
|
+
out.push("7. \u914D\u7F6E\u89E3\u91CA\uFF1Afulgurjs explain\uFF1B\u90E8\u7F72\u4F53\u68C0\uFF1Afulgurjs doctor --base <URL> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55...>");
|
|
515
|
+
if (consume) {
|
|
516
|
+
out.push(" \uFF08--apps \u662F\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u4E0D\u662F\u5BB9\u5668\u540D\uFF09");
|
|
517
|
+
out.push("8. \u4EC5\u9010\u9875\u63A5\u5165\u7684\u5BBF\u4E3B\uFF1A\u9875\u9762\u5951\u7EA6\u6838\u5BF9 fulgurjs check-pages\uFF08--manifest/--site \u6307\u5B9A\u8FDC\u7A0B manifest \u6765\u6E90\uFF09\uFF1B");
|
|
518
|
+
out.push(" \u672A\u914D\u7F6E hostPages \u7684\u5DE5\u7A0B\u8FD0\u884C check-pages \u4F1A\u660E\u786E\u63D0\u793A\u300C\u672A\u914D\u7F6E\u8BE5\u80FD\u529B\u300D\uFF0C\u4E0D\u4EA7\u51FA\u4F2A\u6838\u5BF9");
|
|
519
|
+
} else {
|
|
520
|
+
out.push("8. \u9010\u9875\u63A5\u5165\uFF08\u5BBF\u4E3B\u9875\u9762\u8DEF\u7531\u8868\uFF09\u662F\u53EF\u9009\u9879\u2014\u2014\u7EAF\u63D0\u4F9B\u65B9\u65E0\u9700 check-pages/hostPages");
|
|
521
|
+
}
|
|
522
|
+
out.push("9. \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");
|
|
523
|
+
return out;
|
|
524
|
+
}
|
|
425
525
|
function appModeSummary(loaded) {
|
|
426
526
|
const options = loaded.options;
|
|
427
527
|
const roleText = { host: "\u5BBF\u4E3B", remote: "\u8FDC\u7A0B", dual: "\u5BBF\u4E3B+\u8FDC\u7A0B\uFF08\u53CC\u89D2\u8272\uFF09" }[Object.keys(options.remotes ?? {}).length > 0 && (Object.keys(options.exposes ?? {}).length > 0 || !!options.setup) ? "dual" : Object.keys(options.remotes ?? {}).length > 0 ? "host" : "remote"];
|
|
@@ -440,87 +540,81 @@ function appModeSummary(loaded) {
|
|
|
440
540
|
if (loaded.hostPages) {
|
|
441
541
|
lines.push(` \u9875\u9762\u8DEF\u7531\u8868\uFF08hostPages \u5177\u540D\u5BFC\u51FA\uFF09\uFF1A${loaded.hostPages.pages.length} \u6761`);
|
|
442
542
|
} else {
|
|
443
|
-
lines.push(" \u9875\u9762\u8DEF\u7531\u8868\uFF1A\uFF08\u65E0 hostPages \u5BFC\u51FA\u2014\u2014\
|
|
543
|
+
lines.push(" \u9875\u9762\u8DEF\u7531\u8868\uFF1A\uFF08\u65E0 hostPages \u5BFC\u51FA\u2014\u2014\u672A\u7528\u9010\u9875\u63A5\u5165\uFF0Ccheck-pages \u4E0D\u9002\u7528\uFF09");
|
|
444
544
|
}
|
|
445
545
|
return lines;
|
|
446
546
|
}
|
|
447
547
|
async function inspectConfig(configPath) {
|
|
448
548
|
const loaded = await loadAppConfig(configPath);
|
|
549
|
+
const options = loaded.options;
|
|
550
|
+
const isHost = Object.keys(options.remotes ?? {}).length > 0;
|
|
551
|
+
const isRemote = Object.keys(options.exposes ?? {}).length > 0 || !!options.setup;
|
|
552
|
+
const role = isHost && isRemote ? "dual" : isHost ? "consumer" : "provider";
|
|
553
|
+
let framework = "vue";
|
|
554
|
+
let frameworkNote = "";
|
|
555
|
+
try {
|
|
556
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(loaded.appRoot, "package.json"), "utf8"));
|
|
557
|
+
const detected = detectFrameworkFromPackageJson(pkg);
|
|
558
|
+
if (detected) framework = detected;
|
|
559
|
+
else frameworkNote = "\n \uFF08\u672A\u80FD\u4ECE package.json \u5224\u65AD\u6846\u67B6\u2014\u2014\u4EE5\u4E0B\u5165\u53E3\u63D0\u793A\u6309 Vue \u7ED9\u51FA\uFF1BReact \u9879\u76EE\u8BF7\u6539\u7528 @fulgurjs/federation/react\uFF09";
|
|
560
|
+
} catch {
|
|
561
|
+
frameworkNote = "\n \uFF08\u672A\u8BFB\u53D6\u5230\u5E94\u7528 package.json\u2014\u2014\u4EE5\u4E0B\u5165\u53E3\u63D0\u793A\u6309 Vue \u7ED9\u51FA\uFF1BReact \u9879\u76EE\u8BF7\u6539\u7528 @fulgurjs/federation/react\uFF09";
|
|
562
|
+
}
|
|
449
563
|
const out = [];
|
|
450
564
|
out.push(`${MARK} \u914D\u7F6E\u6821\u9A8C\u901A\u8FC7\uFF1A\u5355\u9879\u76EE\u5F62\u6001\uFF08\u9ED8\u8BA4\u5BFC\u51FA = federation() \u9009\u9879\uFF09`);
|
|
451
565
|
out.push("\u5E94\u7528\u6458\u8981\uFF1A");
|
|
452
566
|
out.push(...appModeSummary(loaded));
|
|
453
567
|
out.push("\n\u2500\u2500 vite.config.ts plugins \u63A5\u5165\u5757\uFF08\u8FD9\u5C31\u662F\u5168\u90E8\u8054\u90A6\u63A5\u5165\u4EE3\u7801\uFF09 \u2500\u2500");
|
|
454
568
|
out.push(viteSnippetForAppMode(loaded.appRoot));
|
|
455
|
-
out.push("\n\u2500\u2500 \u63A5\u5165\u6838\u5BF9\u6E05\u5355\uFF08\
|
|
456
|
-
out.push(...
|
|
569
|
+
out.push("\n\u2500\u2500 \u63A5\u5165\u6838\u5BF9\u6E05\u5355\uFF08\u6309\u672C\u914D\u7F6E\u7684\u89D2\u8272\u751F\u6210\uFF0C\u4E0E\u5177\u4F53\u9879\u76EE\u65E0\u5173\uFF09 \u2500\u2500");
|
|
570
|
+
out.push(...checklistFor({ framework, role }).map((line) => line.startsWith("5.") ? line + frameworkNote : line));
|
|
457
571
|
return out.join("\n");
|
|
458
572
|
}
|
|
459
|
-
var MARK, STARTER_CONFIG, COMMON_CHECKLIST;
|
|
573
|
+
var MARK, REMOTES_EXAMPLE, EXPOSES_EXAMPLE, HOST_PAGES_COMMENT, STARTER_CONFIG, APP_ENTRY_NOTE, COMMON_CHECKLIST;
|
|
460
574
|
var init_init = __esm({
|
|
461
575
|
"src/init.ts"() {
|
|
462
576
|
"use strict";
|
|
463
577
|
init_app_config();
|
|
464
578
|
MARK = "[fulgurjs:init]";
|
|
465
|
-
|
|
466
|
-
//
|
|
467
|
-
// Vite \u63A5\u5165\uFF08\u672C\u9879\u76EE vite.config.ts \u53EA\u9700\u4E24\u884C\u8054\u90A6\u76F8\u5173\u4EE3\u7801\uFF09\uFF1A
|
|
468
|
-
// import federation from '@fulgurjs/federation'
|
|
469
|
-
// import fulgurjsConfig from './fulgurjs.config'
|
|
470
|
-
// // plugins: [ ...\u539F\u6709\u63D2\u4EF6, federation(fulgurjsConfig) ]
|
|
471
|
-
//
|
|
472
|
-
// CLI\uFF08\u7EAF\u672C\u5730\uFF0C\u65E0\u7F51\u7EDC\uFF09\uFF1A
|
|
473
|
-
// npx fulgurjs explain # \u89E3\u91CA\u672C\u5E94\u7528\u6709\u6548\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE
|
|
474
|
-
// npx fulgurjs check-pages # \u5BBF\u4E3B\u9875\u9762\u8868 \u2194 \u8FDC\u7A0B manifest \u5951\u7EA6\u6838\u5BF9
|
|
475
|
-
// npx fulgurjs doctor --base http://<\u7AD9\u70B9> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55> # \u90E8\u7F72\u4F53\u68C0\uFF08\u90E8\u7F72\u5728 /my-remote/ \u5C31\u5199 my-remote\uFF09
|
|
476
|
-
import type { FederationOptions } from '@fulgurjs/federation'
|
|
477
|
-
|
|
478
|
-
export default {
|
|
479
|
-
// \u8054\u90A6\u5BB9\u5668\u540D\uFF08\u8FDC\u7A0B\u5F15\u7528\u5B83\u65F6\u7528\u8FD9\u4E2A\u540D\uFF1B\u540C\u4E00\u9875\u9762\u5185\u552F\u4E00\uFF09
|
|
480
|
-
name: 'my-app',
|
|
481
|
-
// \u672C\u5E94\u7528\u5BF9\u5916\u66B4\u9732\u7684\u6A21\u5757\uFF1A'./\u952E' \u2192 \u76F8\u5BF9\u672C\u9879\u76EE\u6839\u7684\u6E90\u6587\u4EF6\u8DEF\u5F84
|
|
482
|
-
exposes: {
|
|
483
|
-
'./pages/home': './src/views/Home.vue',
|
|
484
|
-
},
|
|
485
|
-
// \u672C\u5E94\u7528\u6D88\u8D39\u7684\u8FDC\u7A0B\uFF08\u952E = import \u524D\u7F00\uFF1Bdev/prod \u5730\u5740\u4E8C\u6BB5\u5F0F\uFF0C\u5355\u5730\u5740\u5B57\u7B26\u4E32\u4E5F\u884C\uFF09
|
|
579
|
+
REMOTES_EXAMPLE = ` // \u672C\u5E94\u7528\u6D88\u8D39\u7684\u8FDC\u7A0B\uFF08\u952E = import \u524D\u7F00\uFF1Bdev/prod \u5730\u5740\u4E8C\u6BB5\u5F0F\uFF0C\u5355\u5730\u5740\u5B57\u7B26\u4E32\u4E5F\u884C\uFF09
|
|
486
580
|
remotes: {
|
|
487
581
|
'remote-a': { dev: 'http://localhost:5174/remote-a', prod: '/remote-a' },
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// \
|
|
491
|
-
// \
|
|
492
|
-
//
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
582
|
+
},`;
|
|
583
|
+
EXPOSES_EXAMPLE = {
|
|
584
|
+
vue: ` // \u672C\u5E94\u7528\u5BF9\u5916\u66B4\u9732\u7684\u6A21\u5757\uFF1A'./\u952E' \u2192 \u76F8\u5BF9\u672C\u9879\u76EE\u6839\u7684\u6E90\u6587\u4EF6\u8DEF\u5F84
|
|
585
|
+
// \u666E\u901A\u7EC4\u4EF6/\u51FD\u6570\u6A21\u5757\u53EF\u76F4\u63A5 expose\uFF08\u4F7F\u7528\u65B9 remoteComponent/loadRemote \u6D88\u8D39\uFF0Cprops \u89C1\u7EC4\u4EF6\u5951\u7EA6\uFF09\uFF1B
|
|
586
|
+
// \u53EA\u6709\u4F5C\u4E3A\u300C\u9875\u9762\u300D\u63A5\u5165\uFF08\u5BBF\u4E3B\u9875\u9762\u8DEF\u7531\u8868\uFF09\u65F6\u624D\u8981\u6C42\u72EC\u7ACB\u9875\uFF08\u4ECE\u8DEF\u7531\u53D6\u53C2\uFF09
|
|
587
|
+
exposes: {
|
|
588
|
+
'./shared/user-badge': './src/components/UserBadge.vue',
|
|
589
|
+
},`,
|
|
590
|
+
react: ` // \u672C\u5E94\u7528\u5BF9\u5916\u66B4\u9732\u7684\u6A21\u5757\uFF1A'./\u952E' \u2192 \u76F8\u5BF9\u672C\u9879\u76EE\u6839\u7684\u6E90\u6587\u4EF6\u8DEF\u5F84
|
|
591
|
+
// \u666E\u901A\u7EC4\u4EF6/\u51FD\u6570\u6A21\u5757\u53EF\u76F4\u63A5 expose\uFF08\u4F7F\u7528\u65B9 remoteComponent/loadRemote \u6D88\u8D39\uFF0Cprops \u89C1\u7EC4\u4EF6\u5951\u7EA6\uFF09\uFF1B
|
|
592
|
+
// \u53EA\u6709\u4F5C\u4E3A\u300C\u9875\u9762\u300D\u63A5\u5165\uFF08\u5BBF\u4E3B\u9875\u9762\u8DEF\u7531\u8868\uFF09\u65F6\u624D\u8981\u6C42\u72EC\u7ACB\u9875\uFF08\u4ECE\u8DEF\u7531\u53D6\u53C2\uFF09
|
|
593
|
+
exposes: {
|
|
594
|
+
'./shared/user-badge': './src/components/UserBadge.tsx',
|
|
595
|
+
},`
|
|
596
|
+
};
|
|
597
|
+
HOST_PAGES_COMMENT = `// \u2500\u2500 \u4EE5\u4E0B\u4EC5\u4F9B\u9010\u9875\u63A5\u5165\u7684\u5BBF\u4E3B\u4F7F\u7528\uFF08\u4E0D\u662F federation() \u7684\u53C2\u6570\uFF09\u2500\u2500
|
|
598
|
+
// \u9010\u9875\u63A5\u5165\uFF08\u5BBF\u4E3B\u9875\u9762\u8DEF\u7531\u8868 \u2192 \u8FDC\u7A0B\u9875\u9762\uFF09\u65F6\uFF0C\u628A\u9875\u9762\u8DEF\u7531\u8868\u4EE5\u5177\u540D\u5BFC\u51FA hostPages \u63D0\u4F9B\u7ED9 CLI\uFF0C
|
|
599
|
+
// \u4E0E\u8FD0\u884C\u65F6 createHostPages \u6D88\u8D39\u540C\u4E00\u4EFD\u6570\u636E\u6A21\u5757\uFF08\u552F\u4E00\u624B\u5DE5\u7EF4\u62A4\u4F4D\u7F6E\uFF09\u3002
|
|
503
600
|
// \u7EAF\u6570\u636E\u6A21\u5757\u793A\u4F8B src/fulgurjs/host/pages.data.ts\uFF1A
|
|
504
601
|
// export const remotePrefixes = { '/remote-a/': 'remote-a' }
|
|
505
602
|
// export const pages = [{ route: '/remote-a/home', name: 'Home', title: '\u9996\u9875' }]
|
|
506
603
|
// import { pages, remotePrefixes } from './src/fulgurjs/host/pages.data'
|
|
507
604
|
// export const hostPages = { pages, remotePrefixes }
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
" \u90E8\u7F72\u4F53\u68C0\uFF1Afulgurjs doctor --base <URL> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55...>\uFF08--apps \u662F\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u4E0D\u662F\u5BB9\u5668\u540D\uFF09",
|
|
522
|
-
"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"
|
|
523
|
-
];
|
|
605
|
+
//
|
|
606
|
+
// \u4E0D\u7528\u9010\u9875\u63A5\u5165\uFF08\u5B8C\u6574\u5B50\u5E94\u7528\u6865\u63A5 / \u666E\u901A\u7EC4\u4EF6\u6D88\u8D39\uFF09\u5219\u5220\u9664\u672C\u6BB5\u2014\u2014\u4E1A\u52A1\u83DC\u5355\u4E0E\u4E1A\u52A1 Router
|
|
607
|
+
// \u4ECD\u5F52\u5E94\u7528\u81EA\u5DF1\u7BA1\u7406\uFF0C\u8054\u90A6\u4E0D\u63A5\u7BA1\u3002`;
|
|
608
|
+
STARTER_CONFIG = starterConfigFor({ framework: "vue", role: "dual" });
|
|
609
|
+
APP_ENTRY_NOTE = {
|
|
610
|
+
vue: `5. Vue \u5E94\u7528\u4EE3\u7801\u552F\u4E00 API \u5165\u53E3\uFF1Aimport { loadRemote, remoteComponent, createHostPages, provideAppContext, getAppContext, clearAppContext, definePages, remoteSchema } from '@fulgurjs/federation/vue'
|
|
611
|
+
\uFF08\u5B8C\u6574\u5B50\u5E94\u7528\u6865\u63A5\u53E6\u52A0 createVueBridgeApp / defineBridgeApp\uFF1BURL \u540C\u6B65\u53E6\u52A0 createVueBridgeNavigation / connectVueBridgeRouter\u2014\u2014\u540C\u4E00\u5165\u53E3\u3002
|
|
612
|
+
\u6846\u67B6\u65E0\u5173\u6A21\u5757\uFF08\u7EAF JS/TS \u6D88\u8D39\u3001\u65E0 Vue\uFF09\u7528 @fulgurjs/federation/runtime\uFF09`,
|
|
613
|
+
react: `5. React \u5E94\u7528\u4EE3\u7801\u552F\u4E00 API \u5165\u53E3\uFF1Aimport { loadRemote, remoteComponent, useLoadRemote, RemoteErrorBoundary, createReactHostPages, provideAppContext, getAppContext, clearAppContext, definePages, remoteSchema } from '@fulgurjs/federation/react'
|
|
614
|
+
\uFF08\u5B8C\u6574\u5B50\u5E94\u7528\u6865\u63A5\u53E6\u52A0 createReactBridgeApp / defineBridgeApp\uFF1BURL \u540C\u6B65\u53E6\u52A0 createReactBridgeNavigation / createReactBridgeRouter\u2014\u2014\u540C\u4E00\u5165\u53E3\u3002
|
|
615
|
+
\u6846\u67B6\u65E0\u5173\u6A21\u5757\uFF08\u7EAF JS/TS \u6D88\u8D39\u3001\u65E0 React\uFF09\u7528 @fulgurjs/federation/runtime\uFF09`
|
|
616
|
+
};
|
|
617
|
+
COMMON_CHECKLIST = checklistFor({ framework: "vue", role: "dual" });
|
|
524
618
|
}
|
|
525
619
|
});
|
|
526
620
|
|
|
@@ -535,11 +629,13 @@ __export(create_exports, {
|
|
|
535
629
|
defaultInstall: () => defaultInstall,
|
|
536
630
|
formatCreateResult: () => formatCreateResult,
|
|
537
631
|
isExcluded: () => isExcluded,
|
|
538
|
-
|
|
632
|
+
nodeEnginesViolation: () => nodeEnginesViolation,
|
|
539
633
|
packageRootOf: () => packageRootOf,
|
|
634
|
+
pnpmUnavailableReason: () => pnpmUnavailableReason,
|
|
540
635
|
readDevConfig: () => readDevConfig,
|
|
541
636
|
resolveTemplatesRoot: () => resolveTemplatesRoot,
|
|
542
637
|
scanTemplateConflicts: () => scanTemplateConflicts,
|
|
638
|
+
templateEnginesNode: () => templateEnginesNode,
|
|
543
639
|
validateTemplateDir: () => validateTemplateDir
|
|
544
640
|
});
|
|
545
641
|
import fs2 from "node:fs";
|
|
@@ -669,15 +765,18 @@ function formatCreateResult(result) {
|
|
|
669
765
|
for (const c of result.skippedConflicts) lines.push(` ${c.rel} \u2014 ${c.reason}`);
|
|
670
766
|
}
|
|
671
767
|
lines.push("\u540E\u7EED\u6B65\u9AA4\uFF1A");
|
|
672
|
-
lines.push(` cd ${result.target}`);
|
|
768
|
+
lines.push(` cd "${result.target}"`);
|
|
673
769
|
if (!result.installRan) lines.push(" pnpm install --frozen-lockfile");
|
|
674
770
|
lines.push(" pnpm dev # \u6309\u542F\u52A8\u987A\u5E8F\u62C9\u8D77\u5168\u90E8\u5E94\u7528\uFF0C\u5931\u8D25\u4F1A\u6574\u7EC4\u9000\u51FA\u5E76\u8BF4\u660E\u539F\u56E0");
|
|
675
771
|
lines.push("\u8BBF\u95EE\u5165\u53E3\uFF08\u8FDC\u7A0B\u5148\u4E8E\u5BBF\u4E3B\u5C31\u7EEA\uFF09\uFF1A");
|
|
676
772
|
for (const app of apps) {
|
|
677
773
|
lines.push(` http://localhost:${app.port}/ ${app.name}${app.dir !== app.name ? `\uFF08\u76EE\u5F55 ${app.dir}\uFF09` : ""}`);
|
|
678
774
|
}
|
|
679
|
-
const hosts = apps.
|
|
680
|
-
|
|
775
|
+
const hosts = apps.filter((a) => a.host);
|
|
776
|
+
const hostList = hosts.length ? hosts : apps.slice(-1);
|
|
777
|
+
lines.push(
|
|
778
|
+
"\u6D4F\u89C8\u5668\u6253\u5F00\u5BBF\u4E3B\u5165\u53E3\uFF1A" + hostList.map((a) => `http://localhost:${a.port}/\uFF08${a.name}\uFF09`).join(" ")
|
|
779
|
+
);
|
|
681
780
|
lines.push(" pnpm build # \u5404\u5B50\u5E94\u7528\u751F\u4EA7\u6784\u5EFA\uFF08\u8FDC\u7A0B\u751F\u6210 fulgurjs-remoteEntry.js / fulgurjs-manifest.json\uFF09");
|
|
682
781
|
lines.push(" \u90E8\u7F72\u89C4\u5219\uFF08no-cache / SPA \u56DE\u9000 / base \u5BF9\u9F50\uFF09\u89C1\u6A21\u677F\u5185\u5404\u5B50\u5E94\u7528 README\uFF1B\u90E8\u7F72\u540E\u53EF\u7528 npx fulgurjs doctor --base <\u7AD9\u70B9> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55> \u4F53\u68C0");
|
|
683
782
|
lines.push(" \u6539\u7AEF\u53E3\uFF08\u56DB\u5904\u540C\u6B65\uFF0C\u6F0F\u4E00\u5904\u542F\u52A8\u5668\u4F1A\u88AB\u65E7\u7AEF\u53E3\u5361\u4F4F\uFF09\uFF1A");
|
|
@@ -708,10 +807,23 @@ function formatCreateJson(result) {
|
|
|
708
807
|
2
|
|
709
808
|
);
|
|
710
809
|
}
|
|
711
|
-
function
|
|
810
|
+
function nodeEnginesViolation(nodeVersion, range) {
|
|
811
|
+
if (!range) return void 0;
|
|
812
|
+
const m = range.trim().match(/^>=?(\d+)\.(\d+)(?:\.(\d+))?/);
|
|
813
|
+
if (!m) return void 0;
|
|
814
|
+
const parse = (v) => v.replace(/^v/, "").split(/[.-]/).map((x) => Number(x) || 0);
|
|
815
|
+
const [curMajor, curMinor = 0, curPatch = 0] = parse(nodeVersion);
|
|
816
|
+
const [minMajor, minMinor = 0, minPatch = 0] = [Number(m[1]), Number(m[2] ?? 0), Number(m[3] ?? 0)];
|
|
817
|
+
const ge = (a, b) => a[0] !== b[0] ? a[0] > b[0] : a[1] !== b[1] ? a[1] > b[1] : (a[2] ?? 0) >= (b[2] ?? 0);
|
|
818
|
+
if (range.startsWith(">=")) {
|
|
819
|
+
if (!ge([curMajor, curMinor, curPatch], [minMajor, minMinor, minPatch])) {
|
|
820
|
+
return `\u5F53\u524D Node ${nodeVersion} \u4E0D\u6EE1\u8DB3\u6A21\u677F\u8981\u6C42 engines.node ${range}`;
|
|
821
|
+
}
|
|
822
|
+
return void 0;
|
|
823
|
+
}
|
|
712
824
|
const major = Number(nodeVersion.replace(/^v/, "").split(".")[0]);
|
|
713
|
-
if (Number.isFinite(major) && major <
|
|
714
|
-
return `\u5F53\u524D Node ${nodeVersion} \u4F4E\u4E8E\u6A21\u677F\u8981\u6C42
|
|
825
|
+
if (Number.isFinite(major) && major < minMajor) {
|
|
826
|
+
return `\u5F53\u524D Node ${nodeVersion} \u4F4E\u4E8E\u6A21\u677F\u8981\u6C42 engines.node ${range}`;
|
|
715
827
|
}
|
|
716
828
|
return void 0;
|
|
717
829
|
}
|
|
@@ -746,9 +858,22 @@ async function createProject(opts, io) {
|
|
|
746
858
|
);
|
|
747
859
|
}
|
|
748
860
|
}
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
861
|
+
const enginesViolation = nodeEnginesViolation(process.version, templateEnginesNode(templateDir));
|
|
862
|
+
if (enginesViolation) {
|
|
863
|
+
throw new Error(
|
|
864
|
+
`[fulgurjs:create] \u73AF\u5883\u6821\u9A8C\u5931\u8D25\uFF1A${enginesViolation}
|
|
865
|
+
\u4FEE\u6CD5\uFF1A\u5347\u7EA7 Node\uFF08nvm install <\u7248\u672C> && nvm use <\u7248\u672C>\uFF0C\u6216\u4ECE https://nodejs.org \u5B89\u88C5 LTS\uFF09\u540E\u91CD\u8BD5\uFF1B\u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6`
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
if (opts.install) {
|
|
869
|
+
const pnpmMissing = await pnpmUnavailableReason();
|
|
870
|
+
if (pnpmMissing) {
|
|
871
|
+
throw new Error(
|
|
872
|
+
`[fulgurjs:create] \u73AF\u5883\u6821\u9A8C\u5931\u8D25\uFF1A${pnpmMissing}
|
|
873
|
+
\u4FEE\u6CD5\uFF1Acorepack enable\uFF08Node \u81EA\u5E26\uFF09\uFF0C\u6216 npm i -g pnpm\uFF1B\u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6`
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
752
877
|
let outcome;
|
|
753
878
|
try {
|
|
754
879
|
if (fs2.existsSync(target) && fs2.readdirSync(target).length > 0) {
|
|
@@ -791,7 +916,6 @@ async function createProject(opts, io) {
|
|
|
791
916
|
} else {
|
|
792
917
|
io.log("[fulgurjs:create] \u6309\u8981\u6C42\u8DF3\u8FC7\u5B89\u88C5\uFF08--no-install\uFF09\uFF1A\u8FDB\u5165\u76EE\u5F55\u540E\u5148\u6267\u884C pnpm install --frozen-lockfile");
|
|
793
918
|
}
|
|
794
|
-
for (const w of warnings) io.log(`[fulgurjs:create] \u8B66\u544A\uFF1A${w}`);
|
|
795
919
|
const result = {
|
|
796
920
|
template: templateName,
|
|
797
921
|
target,
|
|
@@ -806,6 +930,24 @@ async function createProject(opts, io) {
|
|
|
806
930
|
else io.log(formatCreateResult(result));
|
|
807
931
|
return result;
|
|
808
932
|
}
|
|
933
|
+
function templateEnginesNode(templateDir) {
|
|
934
|
+
try {
|
|
935
|
+
const pkg = JSON.parse(fs2.readFileSync(path2.join(templateDir, "package.json"), "utf8"));
|
|
936
|
+
return pkg.engines?.node;
|
|
937
|
+
} catch {
|
|
938
|
+
return void 0;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
async function pnpmUnavailableReason() {
|
|
942
|
+
const code = await new Promise((resolve2) => {
|
|
943
|
+
const child = spawn("pnpm", ["--version"], { stdio: "ignore" });
|
|
944
|
+
child.once("error", () => resolve2(127));
|
|
945
|
+
child.once("close", (c) => resolve2(c ?? 1));
|
|
946
|
+
});
|
|
947
|
+
if (code === 127) return "pnpm \u672A\u5B89\u88C5\u6216\u4E0D\u5728 PATH";
|
|
948
|
+
if (code !== 0) return `pnpm --version \u9000\u51FA\u7801 ${code}\uFF08pnpm \u5B89\u88C5\u5F02\u5E38\uFF09`;
|
|
949
|
+
return void 0;
|
|
950
|
+
}
|
|
809
951
|
function defaultInstall(cwd, output = "inherit") {
|
|
810
952
|
return new Promise((resolve2) => {
|
|
811
953
|
const child = output === "inherit" ? spawn("pnpm", ["install", "--frozen-lockfile"], { cwd, stdio: "inherit" }) : spawn("pnpm", ["install", "--frozen-lockfile"], { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -1284,6 +1426,110 @@ var init_commands = __esm({
|
|
|
1284
1426
|
}
|
|
1285
1427
|
});
|
|
1286
1428
|
|
|
1429
|
+
// src/port.ts
|
|
1430
|
+
var port_exports = {};
|
|
1431
|
+
__export(port_exports, {
|
|
1432
|
+
applyPortChange: () => applyPortChange,
|
|
1433
|
+
formatPortPlan: () => formatPortPlan,
|
|
1434
|
+
planPortChange: () => planPortChange
|
|
1435
|
+
});
|
|
1436
|
+
import fs4 from "node:fs";
|
|
1437
|
+
import path3 from "node:path";
|
|
1438
|
+
function readDevConfig2(root) {
|
|
1439
|
+
const file = path3.join(root, "scripts", "dev.config.json");
|
|
1440
|
+
if (!fs4.existsSync(file)) {
|
|
1441
|
+
throw new Error(
|
|
1442
|
+
"[fulgurjs:port] \u672A\u627E\u5230 scripts/dev.config.json\u2014\u2014\u672C\u547D\u4EE4\u7528\u4E8E\u6A21\u677F\u5DE5\u7A0B\uFF08create \u751F\u6210\uFF09\u3002\n \u4FEE\u6CD5\uFF1A\u5728\u6A21\u677F\u5DE5\u7A0B\u6839\u76EE\u5F55\u8FD0\u884C\uFF1B\u81EA\u5EFA\u5DE5\u7A0B\u8BF7\u6309\u6587\u6863\u56DB\u5904\u6E05\u5355\u624B\u5DE5\u6539\u7AEF\u53E3"
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
return JSON.parse(fs4.readFileSync(file, "utf8"));
|
|
1446
|
+
}
|
|
1447
|
+
function replacePort(text, from, to) {
|
|
1448
|
+
const re = new RegExp(`(?<![0-9])${from}(?![0-9])`, "g");
|
|
1449
|
+
let hits = 0;
|
|
1450
|
+
const out = text.replace(re, () => {
|
|
1451
|
+
hits++;
|
|
1452
|
+
return String(to);
|
|
1453
|
+
});
|
|
1454
|
+
return { text: out, hits };
|
|
1455
|
+
}
|
|
1456
|
+
function planPortChange(root, app, to) {
|
|
1457
|
+
const cfg = readDevConfig2(root);
|
|
1458
|
+
const target = cfg.apps.find((a) => a.name === app || a.dir === app);
|
|
1459
|
+
if (!target) {
|
|
1460
|
+
throw new Error(
|
|
1461
|
+
`[fulgurjs:port] dev.config.json \u4E2D\u6CA1\u6709\u5E94\u7528\u300C${app}\u300D\u3002\u73B0\u6709\u5E94\u7528\uFF1A${cfg.apps.map((a) => a.name).join("\u3001")}`
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
const from = target.port;
|
|
1465
|
+
if (from === to) {
|
|
1466
|
+
throw new Error(`[fulgurjs:port] ${app} \u5DF2\u662F\u7AEF\u53E3 ${to}\uFF0C\u65E0\u9700\u53D8\u66F4`);
|
|
1467
|
+
}
|
|
1468
|
+
const notes = [];
|
|
1469
|
+
const candidates = [
|
|
1470
|
+
{ file: path3.join(root, target.dir, "package.json"), required: true },
|
|
1471
|
+
{ file: path3.join(root, "scripts", "dev.config.json"), required: true },
|
|
1472
|
+
{ file: path3.join(root, "fulgurjs.config.ts"), required: false },
|
|
1473
|
+
{ file: path3.join(root, "README.md"), required: false }
|
|
1474
|
+
];
|
|
1475
|
+
for (const a of cfg.apps) {
|
|
1476
|
+
if (a.host && a.dir !== target.dir) {
|
|
1477
|
+
candidates.push({ file: path3.join(root, a.dir, "fulgurjs.config.ts"), required: false });
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
const plans = [];
|
|
1481
|
+
for (const c of candidates) {
|
|
1482
|
+
if (!fs4.existsSync(c.file)) {
|
|
1483
|
+
if (c.required) plans.push({ file: c.file, hits: 0, status: "missing-file" });
|
|
1484
|
+
continue;
|
|
1485
|
+
}
|
|
1486
|
+
const text = fs4.readFileSync(c.file, "utf8");
|
|
1487
|
+
const { hits } = replacePort(text, from, to);
|
|
1488
|
+
plans.push({ file: c.file, hits, status: hits > 0 ? "planned" : "not-found" });
|
|
1489
|
+
}
|
|
1490
|
+
if (!plans.some((p) => p.status === "planned")) {
|
|
1491
|
+
throw new Error(
|
|
1492
|
+
`[fulgurjs:port] \u65E7\u7AEF\u53E3 ${from} \u672A\u5728\u4EFB\u4F55\u53D7\u5F71\u54CD\u6587\u4EF6\u4E2D\u51FA\u73B0\u2014\u2014\u5DE5\u7A0B\u53EF\u80FD\u5DF2\u624B\u5DE5\u6539\u8FC7\u3002\u8BF7\u6838\u5BF9 scripts/dev.config.json \u4E0E\u6587\u6863`
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
const notFound = plans.filter((p) => p.status === "not-found" || p.status === "missing-file");
|
|
1496
|
+
if (notFound.length) {
|
|
1497
|
+
notes.push(`\u4EE5\u4E0B\u6587\u4EF6\u672A\u53D1\u73B0\u65E7\u7AEF\u53E3 ${from}\uFF08\u53EF\u80FD\u5DF2\u6539\u6216\u5F62\u6001\u4E0D\u540C\uFF0C\u8BF7\u4EBA\u5DE5\u786E\u8BA4\uFF09\uFF1A${notFound.map((p) => path3.relative(root, p.file)).join("\u3001")}`);
|
|
1498
|
+
}
|
|
1499
|
+
return { app: target.name, dir: target.dir, from, to, plans, notes };
|
|
1500
|
+
}
|
|
1501
|
+
function applyPortChange(root, plan) {
|
|
1502
|
+
let written = 0;
|
|
1503
|
+
for (const p of plan.plans) {
|
|
1504
|
+
if (p.status !== "planned" || p.hits === 0) continue;
|
|
1505
|
+
const text = fs4.readFileSync(p.file, "utf8");
|
|
1506
|
+
const { text: out, hits } = replacePort(text, plan.from, plan.to);
|
|
1507
|
+
if (hits > 0) {
|
|
1508
|
+
fs4.writeFileSync(p.file, out);
|
|
1509
|
+
written++;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return written;
|
|
1513
|
+
}
|
|
1514
|
+
function formatPortPlan(root, plan) {
|
|
1515
|
+
const lines = [];
|
|
1516
|
+
lines.push(`[fulgurjs:port] \u8BA1\u5212\uFF1A${plan.app}\uFF08\u76EE\u5F55 ${plan.dir}\uFF09\u7AEF\u53E3 ${plan.from} \u2192 ${plan.to}`);
|
|
1517
|
+
for (const p of plan.plans) {
|
|
1518
|
+
const rel = path3.relative(root, p.file);
|
|
1519
|
+
if (p.status === "planned") lines.push(` \u6539\u5199 ${rel}\uFF08${p.hits} \u5904\uFF09`);
|
|
1520
|
+
else if (p.status === "not-found") lines.push(` \u8DF3\u8FC7 ${rel}\uFF08\u672A\u53D1\u73B0\u65E7\u7AEF\u53E3 ${plan.from}\uFF09`);
|
|
1521
|
+
else lines.push(` \u8DF3\u8FC7 ${rel}\uFF08\u6587\u4EF6\u4E0D\u5B58\u5728\uFF09`);
|
|
1522
|
+
}
|
|
1523
|
+
for (const n of plan.notes) lines.push(` \u6CE8\uFF1A${n}`);
|
|
1524
|
+
lines.push("\u9884\u89C8\u6A21\u5F0F\u672A\u5199\u76D8\uFF1B\u786E\u8BA4\u65E0\u8BEF\u540E\u52A0 --write \u6267\u884C\u3002\u5199\u5165\u53EF\u7528 git checkout <file> \u56DE\u9000\u3002");
|
|
1525
|
+
return lines.join("\n");
|
|
1526
|
+
}
|
|
1527
|
+
var init_port = __esm({
|
|
1528
|
+
"src/port.ts"() {
|
|
1529
|
+
"use strict";
|
|
1530
|
+
}
|
|
1531
|
+
});
|
|
1532
|
+
|
|
1287
1533
|
// src/cli.ts
|
|
1288
1534
|
import { resolve } from "node:path";
|
|
1289
1535
|
|
|
@@ -1434,8 +1680,9 @@ async function runDoctor(opts) {
|
|
|
1434
1680
|
const perAppShared = [];
|
|
1435
1681
|
const chunkSample = opts.chunkSample ?? 16;
|
|
1436
1682
|
for (const app of opts.apps) {
|
|
1437
|
-
const root = `${opts.base.replace(/\/$/, "")}/${app.replace(/^\//, "")}`;
|
|
1438
|
-
const
|
|
1683
|
+
const root = /^(https?:)?\/\//.test(app) ? app.replace(/\/$/, "") : app === "." || app === "" ? opts.base.replace(/\/$/, "") : `${opts.base.replace(/\/$/, "")}/${app.replace(/^\//, "")}`;
|
|
1684
|
+
const entryName = opts.entry ?? "fulgurjs-remoteEntry.js";
|
|
1685
|
+
const entry = opts.noEntry ? { res: void 0, check: void 0 } : await checkStatus(`${root}/${entryName}`, app, entryName, {
|
|
1439
1686
|
expectJs: true,
|
|
1440
1687
|
expectNoCache: !opts.dev
|
|
1441
1688
|
});
|
|
@@ -1451,7 +1698,7 @@ async function runDoctor(opts) {
|
|
|
1451
1698
|
fix: acao ? void 0 : 'nginx \u5BF9 remoteEntry add_header Access-Control-Allow-Origin "*"'
|
|
1452
1699
|
});
|
|
1453
1700
|
}
|
|
1454
|
-
const manifestRes = await checkStatus(`${root}/fulgurjs-manifest.json`, app, "fulgurjs-manifest.json", {
|
|
1701
|
+
const manifestRes = opts.noManifest ? { res: void 0, check: void 0 } : await checkStatus(`${root}/fulgurjs-manifest.json`, app, "fulgurjs-manifest.json", {
|
|
1455
1702
|
expectNoCache: !opts.dev
|
|
1456
1703
|
});
|
|
1457
1704
|
if (manifestRes.check) checks.push(manifestRes.check);
|
|
@@ -1493,12 +1740,12 @@ async function runDoctor(opts) {
|
|
|
1493
1740
|
}
|
|
1494
1741
|
}
|
|
1495
1742
|
let htmlBody = "";
|
|
1496
|
-
if (!opts.dev) {
|
|
1743
|
+
if (!opts.dev && !opts.noHtml) {
|
|
1497
1744
|
const html = await checkStatus(`${root}/index.html`, app, "index.html", { expectNoCache: true });
|
|
1498
1745
|
if (html.check) checks.push(html.check);
|
|
1499
1746
|
htmlBody = html.res?.body ?? "";
|
|
1500
1747
|
}
|
|
1501
|
-
if (opts.dev) {
|
|
1748
|
+
if (opts.dev && !opts.noEntry) {
|
|
1502
1749
|
const devEntry = await checkStatus(`${root}/@fulgurjs-entry.js`, app, "@fulgurjs-entry.js\uFF08dev \u5BB9\u5668\u5165\u53E3\uFF09", {
|
|
1503
1750
|
expectJs: true
|
|
1504
1751
|
});
|
|
@@ -1597,6 +1844,9 @@ function formatDoctorReport(checks) {
|
|
|
1597
1844
|
// src/cli.ts
|
|
1598
1845
|
var HELP = `fulgurjs \u2014 Vite Module Federation CLI (@fulgurjs/federation)
|
|
1599
1846
|
|
|
1847
|
+
\u5165\u53E3\u9009\u62E9\uFF08\u5E94\u7528\u4EE3\u7801\u5BFC\u5165\uFF09\uFF1AVue \u5E94\u7528 @fulgurjs/federation/vue \uFF5C React \u5E94\u7528 /react \uFF5C
|
|
1848
|
+
\u6846\u67B6\u65E0\u5173\u6A21\u5757 /runtime \uFF5C Vite \u914D\u7F6E\u7528\u5305\u6839\uFF08federation(options)\uFF09\u3002
|
|
1849
|
+
|
|
1600
1850
|
\u65B0\u9879\u76EE\uFF1A\u4ECE\u5B8C\u6574\u6A21\u677F\u521B\u5EFA\u53EF\u72EC\u7ACB\u8FD0\u884C\u7684\u8054\u90A6\u5DE5\u7A0B\uFF08\u590D\u5236\u540E pnpm install + pnpm dev\uFF09\uFF1A
|
|
1601
1851
|
fulgurjs create [--list] \u4EA4\u4E92\u9009\u62E9\u6A21\u677F\uFF08TTY\uFF09
|
|
1602
1852
|
fulgurjs create <\u6A21\u677F> [--dir <\u8DEF\u5F84>] [--no-install] [--force] [--json]
|
|
@@ -1606,28 +1856,42 @@ var HELP = `fulgurjs \u2014 Vite Module Federation CLI (@fulgurjs/federation)
|
|
|
1606
1856
|
\u4FDD\u7559\u4F60\u7684\u7248\u672C\uFF08\u7EDD\u4E0D\u6539\u5199\uFF09\uFF1B--json \u65F6 stdout \u4EC5\u8F93\u51FA\u7ED3\u679C
|
|
1607
1857
|
JSON\uFF0C\u8FDB\u5EA6\u4E0E\u5B89\u88C5\u65E5\u5FD7\u8D70 stderr
|
|
1608
1858
|
\u5DF2\u6709\u9879\u76EE\uFF08\u5355\u9879\u76EE fulgurjs.config.ts \u5728\u5E94\u7528\u6839\u76EE\u5F55\uFF1B\u547D\u4EE4\u9ED8\u8BA4\u8BFB ./fulgurjs.config.ts\uFF09\uFF1A
|
|
1609
|
-
fulgurjs init [--
|
|
1610
|
-
\
|
|
1859
|
+
fulgurjs init [--out <\u8DEF\u5F84>] [--framework vue|react] [--role consumer|provider|dual] [--force]
|
|
1860
|
+
\u751F\u6210\u5355\u9879\u76EE fulgurjs.config.ts \u8D77\u6B65\u6A21\u677F\uFF08\u6700\u5C0F\u6709\u6548\u914D\u7F6E\uFF09\uFF1A
|
|
1861
|
+
\u6846\u67B6\u9ED8\u8BA4\u4ECE package.json \u4F9D\u8D56\u5224\u65AD\uFF08\u5224\u65AD\u4E0D\u4E86\u8981\u6C42\u663E\u5F0F --framework\uFF09\uFF1B
|
|
1862
|
+
\u89D2\u8272\u7F3A\u7701 dual\uFF1B--out \u662F\u8F93\u51FA\u8DEF\u5F84\uFF08\u9ED8\u8BA4 ./fulgurjs.config.ts\uFF1B
|
|
1863
|
+
\u65E7 --template \u5199\u6CD5\u4ECD\u63A5\u53D7\uFF0C\u89C1\u8FC1\u79FB\u6307\u5357\uFF09\uFF1B--force \u8986\u76D6\u5DF2\u5B58\u5728\u7684\u6A21\u677F
|
|
1611
1864
|
fulgurjs init --config <path> \u6821\u9A8C\u914D\u7F6E\uFF1B\u8F93\u51FA federation(fulgurjsConfig) \u63A5\u5165\u5757
|
|
1612
|
-
\u4E0E\u63A5\u5165\u6838\u5BF9\u6E05\u5355
|
|
1865
|
+
\u4E0E\u6309\u89D2\u8272\u7684\u63A5\u5165\u6838\u5BF9\u6E05\u5355
|
|
1613
1866
|
fulgurjs explain [--config <path>] [--json] \u89E3\u91CA\u672C\u5E94\u7528\u6709\u6548\u8054\u90A6\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE\uFF08\u7EAF\u672C\u5730\uFF0C\u65E0\u7F51\u7EDC\uFF09
|
|
1614
1867
|
fulgurjs check-pages [--config <path>] [--site <URL>]
|
|
1615
1868
|
[--manifest <remote>=<\u8DEF\u5F84|URL>]... [--require-verified] [--json]
|
|
1616
|
-
\u6838\u5BF9\u5BBF\u4E3B\u9875\u9762\u8868\u4E0E\u8FDC\u7A0B exposes\uFF08\u5BBF\u4E3B\
|
|
1869
|
+
\u6838\u5BF9\u5BBF\u4E3B\u9875\u9762\u8868\u4E0E\u8FDC\u7A0B exposes\uFF08\u9010\u9875\u63A5\u5165\u7684\u5BBF\u4E3B\u8FD0\u884C\uFF1B
|
|
1870
|
+
\u672A\u914D\u7F6E hostPages \u65F6\u660E\u786E\u63D0\u793A\u4E0D\u9002\u7528\uFF1B
|
|
1617
1871
|
manifest \u6765\u6E90\u4F18\u5148\u7EA7 --manifest > --site/prod \u63A8\u5BFC\uFF0C
|
|
1618
1872
|
\u663E\u5F0F\u6307\u5B9A\u6765\u6E90\u5931\u8D25\u4E0D\u56DE\u9000\uFF1B\u786E\u5B9A\u6027\u9519\u8BEF\u975E\u96F6\u9000\u51FA\uFF1B
|
|
1619
1873
|
--require-verified \u65F6\u65E0\u6CD5\u9A8C\u8BC1\u4E5F\u975E\u96F6\uFF09
|
|
1620
|
-
\
|
|
1621
|
-
fulgurjs
|
|
1874
|
+
\u7AEF\u53E3\u53D8\u66F4\uFF08\u6A21\u677F\u5DE5\u7A0B\uFF1B\u9ED8\u8BA4\u9884\u89C8\uFF0C--write \u624D\u5199\u5165\uFF09\uFF1A
|
|
1875
|
+
fulgurjs port <\u5E94\u7528> <\u65B0\u7AEF\u53E3> [--write] \u4E00\u6B21\u66F4\u65B0\u56DB\u5904\uFF1A\u5E94\u7528 package.json dev/preview\u3001
|
|
1876
|
+
\u5BBF\u4E3B fulgurjs.config.ts \u8BE5\u8FDC\u7A0B dev \u5730\u5740\u3001
|
|
1877
|
+
scripts/dev.config.json\u3001README \u7AEF\u53E3\u8868
|
|
1878
|
+
\u90E8\u7F72\u4F53\u68C0\uFF08--apps \u5FC5\u586B\uFF1A\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u8FDC\u7A0B\u90E8\u7F72\u5728 /remote-a/ \u5C31\u5199 remote-a\uFF1B
|
|
1879
|
+
'.' \u8868\u793A\u90E8\u7F72\u5728\u7AD9\u70B9\u6839\uFF1B\u6761\u76EE\u53EF\u5199\u5B8C\u6574 URL \u68C0\u67E5\u591A origin\uFF1B\u4E0D\u505A\u4EFB\u4F55\u9ED8\u8BA4\u731C\u6D4B\uFF09\uFF1A
|
|
1880
|
+
fulgurjs doctor --base <URL> --apps <a,b,c> [--entry <\u6587\u4EF6\u540D>] [--no-entry]
|
|
1881
|
+
[--no-manifest] [--no-html] [--dev] [--json] [--chunk-sample N]
|
|
1882
|
+
\u9ED8\u8BA4\u68C0\u67E5 remoteEntry/manifest/index.html\uFF1B
|
|
1883
|
+
\u7EAF\u5BBF\u4E3B\u7528 --no-entry\uFF0C\u81EA\u5B9A\u4E49\u5165\u53E3\u6587\u4EF6\u540D\u7528 --entry\uFF0C
|
|
1884
|
+
\u5408\u6CD5\u5173\u95ED manifest \u7528 --no-manifest\uFF0C\u65E0\u9875\u9762\u7528 --no-html
|
|
1622
1885
|
fulgurjs --help
|
|
1623
1886
|
|
|
1624
1887
|
\u793A\u4F8B\uFF1A
|
|
1625
1888
|
fulgurjs create vue-vue --dir my-federation # \u521B\u5EFA\u5B8C\u6574\u5DE5\u7A0B\u5E76\u5B89\u88C5\u4F9D\u8D56\uFF08\u63A8\u8350\u7684\u65B0\u9879\u76EE\u8D77\u70B9\uFF09
|
|
1626
|
-
fulgurjs init
|
|
1889
|
+
fulgurjs init --framework react --role consumer # \u5DF2\u6709 React \u9879\u76EE\u6309\u6D88\u8D39\u65B9\u751F\u6210\u8D77\u6B65\u914D\u7F6E
|
|
1627
1890
|
fulgurjs explain # \u89E3\u91CA\u672C\u5E94\u7528\uFF08--config \u6307\u5411\u5176\u4ED6\u8DEF\u5F84\u65F6\u663E\u5F0F\u4F20\uFF09
|
|
1628
1891
|
fulgurjs check-pages --site http://your-site # \u6309 remotes prod \u5730\u5740\u63A8\u5BFC\u8FDC\u7A0B manifest \u6838\u5BF9
|
|
1629
1892
|
fulgurjs check-pages --manifest remote-a=https://cdn.example.com/remote-a/fulgurjs-manifest.json
|
|
1630
1893
|
fulgurjs doctor --base http://your-site --apps my-app,remote-a
|
|
1894
|
+
|
|
1631
1895
|
`;
|
|
1632
1896
|
async function main() {
|
|
1633
1897
|
const argv = process.argv.slice(2);
|
|
@@ -1653,7 +1917,7 @@ async function main() {
|
|
|
1653
1917
|
return out;
|
|
1654
1918
|
};
|
|
1655
1919
|
if (cmd === "init") {
|
|
1656
|
-
const { writeConfigTemplate: writeConfigTemplate2, inspectConfig: inspectConfig2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
1920
|
+
const { writeConfigTemplate: writeConfigTemplate2, inspectConfig: inspectConfig2, detectFrameworkFromPackageJson: detectFrameworkFromPackageJson2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
1657
1921
|
const configPath = argOf("--config");
|
|
1658
1922
|
if (configPath) {
|
|
1659
1923
|
try {
|
|
@@ -1664,15 +1928,56 @@ async function main() {
|
|
|
1664
1928
|
return 2;
|
|
1665
1929
|
}
|
|
1666
1930
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1931
|
+
if (has("--template")) {
|
|
1932
|
+
console.error(
|
|
1933
|
+
"[fulgurjs:init] --template \u5DF2\u66F4\u540D --out\uFF08\u8F93\u51FA\u8DEF\u5F84\uFF09\n\u6839\u56E0\uFF1A--template \u5728 create \u91CC\u6307\u6A21\u677F\u540D\uFF0C\u5728 init \u91CC\u5374\u662F\u8F93\u51FA\u8DEF\u5F84\u2014\u2014\u540C\u540D\u4E0D\u540C\u4E49\uFF086.0.0 \u53C2\u6570\u6536\u655B\uFF09\n\u4FEE\u6CD5\uFF1Afulgurjs init --out <\u8DEF\u5F84>\uFF08\u672C\u8F6E\u4ECD\u63A5\u53D7 --template \u4F46\u6309 --out \u89E3\u91CA\uFF0C\u540E\u7EED\u7248\u672C\u79FB\u9664\uFF09"
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
const roleArg = argOf("--role") ?? "dual";
|
|
1937
|
+
if (!["consumer", "provider", "dual"].includes(roleArg)) {
|
|
1938
|
+
console.error(`[fulgurjs:init] \u672A\u77E5\u89D2\u8272\uFF1A${roleArg}\uFF08\u53EF\u9009 consumer=\u7EAF\u6D88\u8D39\u65B9 / provider=\u7EAF\u63D0\u4F9B\u65B9 / dual=\u53CC\u89D2\u8272\uFF09`);
|
|
1939
|
+
return 2;
|
|
1940
|
+
}
|
|
1941
|
+
let framework = argOf("--framework");
|
|
1942
|
+
if (framework && !["vue", "react"].includes(framework)) {
|
|
1943
|
+
console.error(`[fulgurjs:init] \u672A\u77E5\u6846\u67B6\uFF1A${framework}\uFF08\u53EF\u9009 vue / react\uFF09`);
|
|
1944
|
+
return 2;
|
|
1945
|
+
}
|
|
1946
|
+
if (!framework) {
|
|
1947
|
+
try {
|
|
1948
|
+
const pkg = JSON.parse(await import("node:fs").then((m) => m.promises.readFile(resolve("package.json"), "utf8")));
|
|
1949
|
+
framework = detectFrameworkFromPackageJson2(pkg) ?? void 0;
|
|
1950
|
+
} catch {
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
if (!framework) {
|
|
1954
|
+
if (process.stdin.isTTY) {
|
|
1955
|
+
const readline = await import("node:readline/promises");
|
|
1956
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1957
|
+
const answer = (await rl.question("\u65E0\u6CD5\u4ECE package.json \u5224\u65AD\u6846\u67B6\uFF0C\u8BF7\u9009\u62E9\uFF08vue / react\uFF09\uFF1A")).trim();
|
|
1958
|
+
rl.close();
|
|
1959
|
+
if (answer !== "vue" && answer !== "react") {
|
|
1960
|
+
console.error("[fulgurjs:init] \u53EA\u652F\u6301 vue / react\uFF1B\u8BF7\u663E\u5F0F\u91CD\u8DD1 fulgurjs init --framework vue|react");
|
|
1961
|
+
return 2;
|
|
1962
|
+
}
|
|
1963
|
+
framework = answer;
|
|
1964
|
+
} else {
|
|
1965
|
+
console.error(
|
|
1966
|
+
"[fulgurjs:init] \u65E0\u6CD5\u4ECE package.json \u5224\u65AD\u6846\u67B6\uFF08vue/react \u4F9D\u8D56\u7F3A\u5931\u6216\u5E76\u5B58\uFF09\u3002\n \u4FEE\u6CD5\uFF1A\u663E\u5F0F\u6307\u5B9A fulgurjs init --framework vue|react\uFF08--role consumer|provider|dual \u53EF\u9009\uFF0C\u9ED8\u8BA4 dual\uFF09"
|
|
1967
|
+
);
|
|
1968
|
+
return 2;
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
const target = resolve(argOf("--out") ?? argOf("--template") ?? "fulgurjs.config.ts");
|
|
1972
|
+
const result = await writeConfigTemplate2(target, has("--force"), { framework, role: roleArg });
|
|
1669
1973
|
if (result === "exists") {
|
|
1670
1974
|
console.error(`[fulgurjs:init] ${target} \u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6\uFF08--force \u5F3A\u5236\u8986\u76D6\uFF09`);
|
|
1671
1975
|
return 2;
|
|
1672
1976
|
}
|
|
1673
|
-
|
|
1977
|
+
const entry = framework === "react" ? "@fulgurjs/federation/react" : "@fulgurjs/federation/vue";
|
|
1978
|
+
console.log(`[fulgurjs:init] \u5DF2\u751F\u6210${framework === "react" ? " React" : " Vue"} ${roleArg === "dual" ? "\u53CC\u89D2\u8272" : roleArg === "consumer" ? "\u7EAF\u6D88\u8D39\u65B9" : "\u7EAF\u63D0\u4F9B\u65B9"}\u8D77\u6B65\u6A21\u677F ${target}
|
|
1674
1979
|
\u540E\u7EED\u6B65\u9AA4\uFF1A
|
|
1675
|
-
1. \u7F16\u8F91 fulgurjs.config.ts\uFF1A\u586B\u5165\u5BB9\u5668\u540D
|
|
1980
|
+
1. \u7F16\u8F91 fulgurjs.config.ts\uFF1A\u586B\u5165\u5BB9\u5668\u540D/${roleArg === "provider" ? "exposes" : roleArg === "consumer" ? "remotes" : "exposes/remotes"}/shared\uFF08\u9ED8\u8BA4\u5BFC\u51FA\u76F4\u63A5\u662F federation() \u9009\u9879\uFF09
|
|
1676
1981
|
2. vite.config.ts \u63A5\u5165\uFF08\u4EC5\u4E24\u884C\u8054\u90A6\u76F8\u5173\u4EE3\u7801\uFF09\uFF1A
|
|
1677
1982
|
import federation from '@fulgurjs/federation'
|
|
1678
1983
|
import fulgurjsConfig from './fulgurjs.config'
|
|
@@ -1680,8 +1985,10 @@ async function main() {
|
|
|
1680
1985
|
3. npx fulgurjs explain # \u6838\u5BF9\u6709\u6548\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE
|
|
1681
1986
|
4. \u90E8\u7F72\u540E\uFF1Anpx fulgurjs doctor --base <URL> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55>
|
|
1682
1987
|
\uFF08--apps \u662F\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u5982\u8FDC\u7A0B\u90E8\u7F72\u5728 /my-remote/ \u5C31\u5199 my-remote\uFF0C\u4E0D\u662F\u5BB9\u5668\u540D\uFF09
|
|
1683
|
-
\
|
|
1684
|
-
\
|
|
1988
|
+
\u5E94\u7528\u4EE3\u7801 API \u5165\u53E3\uFF1A${entry}\uFF08\u6846\u67B6\u65E0\u5173\u6A21\u5757\u7528 /runtime\uFF1B\u8BF4\u660E\u89C1\u6A21\u677F\u5934\u6CE8\u91CA\u4E0E docs \u6587\u6863\u4E2D\u5FC3\uFF09\u3002
|
|
1989
|
+
\u8BF4\u660E\uFF1A\u52A0\u8F7D\u666E\u901A\u7EC4\u4EF6/\u6A21\u5757\u4E0D\u9700\u8981\u9875\u9762\u8868\u3002\u53EA\u6709\u5F53\u5BBF\u4E3B\u7528\u300C\u9875\u9762\u8DEF\u7531\u8868 \u2192 \u8FDC\u7A0B\u9875\u9762\u300D\u65B9\u5F0F\u9010\u9875\u63A5\u5165\u65F6\uFF0C
|
|
1990
|
+
\u624D\u5728 fulgurjs.config.ts \u8FFD\u52A0\u5177\u540D\u5BFC\u51FA hostPages\uFF0C\u5E76\u8FD0\u884C npx fulgurjs check-pages --site <\u7AD9\u70B9> \u6838\u5BF9\uFF1B
|
|
1991
|
+
\u5B8C\u6574\u5B50\u5E94\u7528\u6865\u63A5\u4E0D\u9010\u9875\u767B\u8BB0\u5185\u90E8\u9875\u9762\uFF0C\u4E1A\u52A1\u83DC\u5355\u4E0E Router \u5F52\u5E94\u7528\u81EA\u5DF1\u7BA1\u7406\u3002`);
|
|
1685
1992
|
return 0;
|
|
1686
1993
|
}
|
|
1687
1994
|
if (cmd === "create") {
|
|
@@ -1760,22 +2067,66 @@ async function main() {
|
|
|
1760
2067
|
return 2;
|
|
1761
2068
|
}
|
|
1762
2069
|
}
|
|
2070
|
+
if (cmd === "port") {
|
|
2071
|
+
const app = argv[1] && !argv[1].startsWith("-") ? argv[1] : void 0;
|
|
2072
|
+
const portArg = argv[2] && !argv[2].startsWith("-") ? argv[2] : void 0;
|
|
2073
|
+
if (!app || !portArg || !/^\d+$/.test(portArg)) {
|
|
2074
|
+
console.error("[fulgurjs:port] \u7528\u6CD5\uFF1Afulgurjs port <\u5E94\u7528\u540D> <\u65B0\u7AEF\u53E3> [--write]\uFF08\u9ED8\u8BA4\u53EA\u9884\u89C8\uFF09");
|
|
2075
|
+
return 2;
|
|
2076
|
+
}
|
|
2077
|
+
const { planPortChange: planPortChange2, applyPortChange: applyPortChange2, formatPortPlan: formatPortPlan2 } = await Promise.resolve().then(() => (init_port(), port_exports));
|
|
2078
|
+
try {
|
|
2079
|
+
const plan = planPortChange2(process.cwd(), app, Number(portArg));
|
|
2080
|
+
if (has("--write")) {
|
|
2081
|
+
const written = applyPortChange2(process.cwd(), plan);
|
|
2082
|
+
console.log(`[fulgurjs:port] \u5DF2\u5199\u5165 ${written} \u4E2A\u6587\u4EF6\uFF08${app} ${plan.from} \u2192 ${plan.to}\uFF09\u3002\u56DE\u9000\uFF1Agit checkout <file>`);
|
|
2083
|
+
for (const n of plan.notes) console.log(` \u6CE8\uFF1A${n}`);
|
|
2084
|
+
} else {
|
|
2085
|
+
console.log(formatPortPlan2(process.cwd(), plan));
|
|
2086
|
+
}
|
|
2087
|
+
return 0;
|
|
2088
|
+
} catch (e) {
|
|
2089
|
+
console.error(String(e.message ?? e));
|
|
2090
|
+
return 2;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
1763
2093
|
if (cmd === "doctor") {
|
|
1764
2094
|
const base = argOf("--base");
|
|
1765
|
-
const appsRaw = argOf("--apps")
|
|
2095
|
+
const appsRaw = argOf("--apps");
|
|
1766
2096
|
if (!base) {
|
|
1767
2097
|
console.error("[fulgurjs:doctor] \u7F3A\u5C11 --base <URL>\uFF08\u7AD9\u70B9\u6839\u5730\u5740\uFF0C\u5982 http://your-site\uFF09");
|
|
1768
2098
|
return 2;
|
|
1769
2099
|
}
|
|
2100
|
+
if (!appsRaw) {
|
|
2101
|
+
console.error(
|
|
2102
|
+
'[fulgurjs:doctor] \u7F3A\u5C11 --apps <\u5B50\u76EE\u5F55,...>\u2014\u2014doctor \u4E0D\u731C\u9ED8\u8BA4\u5E94\u7528\u540D\u3002\n \u4FEE\u6CD5\uFF1A--apps \u4F20\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF08\u8FDC\u7A0B\u90E8\u7F72\u5728 /remote-a/ \u5C31\u5199 remote-a\uFF1B\u90E8\u7F72\u5728\u7AD9\u70B9\u6839\u5199 "."\uFF1B\n \u591A origin \u76F4\u63A5\u5199\u5B8C\u6574 URL\uFF09\u3002\u7EAF\u5BBF\u4E3B\u52A0 --no-entry\uFF0C\u81EA\u5B9A\u4E49\u5165\u53E3\u6587\u4EF6\u540D\u7528 --entry <\u6587\u4EF6\u540D>'
|
|
2103
|
+
);
|
|
2104
|
+
return 2;
|
|
2105
|
+
}
|
|
1770
2106
|
const apps = appsRaw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1771
2107
|
const { checks, failed } = await runDoctor({
|
|
1772
2108
|
base,
|
|
1773
2109
|
apps,
|
|
1774
2110
|
dev: has("--dev"),
|
|
1775
|
-
chunkSample: argOf("--chunk-sample") ? Number(argOf("--chunk-sample")) : void 0
|
|
2111
|
+
chunkSample: argOf("--chunk-sample") ? Number(argOf("--chunk-sample")) : void 0,
|
|
2112
|
+
...argOf("--entry") ? { entry: argOf("--entry") } : {},
|
|
2113
|
+
noEntry: has("--no-entry"),
|
|
2114
|
+
noManifest: has("--no-manifest"),
|
|
2115
|
+
noHtml: has("--no-html")
|
|
1776
2116
|
});
|
|
1777
2117
|
if (has("--json")) {
|
|
1778
|
-
console.log(JSON.stringify({
|
|
2118
|
+
console.log(JSON.stringify({
|
|
2119
|
+
base,
|
|
2120
|
+
apps,
|
|
2121
|
+
dev: has("--dev"),
|
|
2122
|
+
mode: {
|
|
2123
|
+
entry: has("--no-entry") ? "(no-entry)" : argOf("--entry") ?? "fulgurjs-remoteEntry.js",
|
|
2124
|
+
manifest: has("--no-manifest") ? "(disabled)" : "fulgurjs-manifest.json",
|
|
2125
|
+
html: has("--no-html") ? "(skipped)" : "index.html"
|
|
2126
|
+
},
|
|
2127
|
+
checks,
|
|
2128
|
+
failed
|
|
2129
|
+
}, null, 2));
|
|
1779
2130
|
} else {
|
|
1780
2131
|
console.log(formatDoctorReport(checks));
|
|
1781
2132
|
}
|