@fulgurjs/federation 6.11.1 → 6.11.3

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # 当前发布说明
2
2
 
3
+ ## 6.11.3
4
+
5
+ - 修复公开入口在应用工厂中动态导入时,SDK 与业务工厂自动合并导致的生产 TLA 等待环;SDK 保持独立分组,保留用户合法的 manualChunks。
6
+ - Vue 声明生成按工具链能力使用官方程序的闭包检查/输出或 dev 增量缓存,避免对运行时动态装配的全部业务页面反复进行无关检查;保持真实 props、推导结果及错误定位。
7
+ - 日志、截图、Markdown 等非类型输入不再触发声明重生成;服务关闭时中止编译、等待退出后清理独占缓存,取消不再误触发系统强杀重试。
8
+ - 修复只有 Vue SFC 的工程被配置解析误报“没有输入”的问题,临时声明配置保留原工程的继承配置。
9
+
10
+ ## 6.11.2
11
+
12
+ - 声明生成单次超时上限从固定 10 分钟改为:默认堆 10 分钟、提堆重试 30 分钟;`FG_DTS_TIMEOUT_MS`(毫秒)可覆盖。大型真实闭包在 8GB 堆下可运行 10 分钟以上,旧上限会在提堆重试阶段被超时强杀并误报为编译错误。
13
+ - 超时强杀(execFile timeout 终止)与「闭包内编译错误」「系统级终止」三类诊断彻底分离:首次超时自动以提堆 + 更长上限重试,仍超时给出 `FG_DTS_TIMEOUT_MS` 修法。
14
+ - 新增超时桩回归(FG_DTS_TIMEOUT_MS 缩短至 400ms 验证强杀路径)。
15
+
16
+
3
17
  ## 6.11.1
4
18
 
5
19
  - 声明生成子进程被系统级终止(OS 内存压力下的 SIGKILL 等:无 V8 堆横幅、无 TS 诊断)时,诊断与「闭包内编译错误」区分:识别终止信号、自动重试一次,仍失败时给出内存压力/外部 kill 的环境修法,不再误报为代码错误。
package/dist/cli.js CHANGED
@@ -3139,7 +3139,7 @@ var RUNTIME_VERSION;
3139
3139
  var init_version = __esm({
3140
3140
  "src/version.ts"() {
3141
3141
  "use strict";
3142
- RUNTIME_VERSION = "6.11.1";
3142
+ RUNTIME_VERSION = "6.11.3";
3143
3143
  }
3144
3144
  });
3145
3145
 
@@ -3634,6 +3634,67 @@ var init_dts_diagnostics = __esm({
3634
3634
  }
3635
3635
  });
3636
3636
 
3637
+ // src/dts-vue-program.ts
3638
+ function genVueDeclarationProgram() {
3639
+ return String.raw`
3640
+ const fs = require('node:fs');
3641
+ const path = require('node:path');
3642
+ const { createRequire } = require('node:module');
3643
+ const req = createRequire(path.join(process.cwd(), 'package.json'));
3644
+ const ts = req('typescript');
3645
+ const vue = req('vue-tsc');
3646
+ const configFile = process.argv[1];
3647
+ const closure = new Set(JSON.parse(process.argv[2]).map(file => path.resolve(file)));
3648
+ const raw = ts.readConfigFile(configFile, ts.sys.readFile);
3649
+ const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path.dirname(configFile), undefined, configFile, undefined, [
3650
+ { extension: '.vue', isMixedContent: true, scriptKind: ts.ScriptKind.Deferred },
3651
+ ]);
3652
+ // 不把 Vue 的映射后诊断序列化到 TS buildinfo;有损的位置不能用于闭包门禁。
3653
+ parsed.options.incremental = false;
3654
+ delete parsed.options.tsBuildInfoFile;
3655
+ const formatHost = {
3656
+ getCurrentDirectory: () => process.cwd(),
3657
+ getCanonicalFileName: file => file,
3658
+ getNewLine: () => '\n',
3659
+ };
3660
+ const diagnostics = [...(raw.error ? [raw.error] : []), ...parsed.errors];
3661
+ if (!diagnostics.length) {
3662
+ const program = vue.createProgram({
3663
+ rootNames: parsed.fileNames,
3664
+ options: parsed.options,
3665
+ host: ts.createCompilerHost(parsed.options),
3666
+ });
3667
+ diagnostics.push(...program.getOptionsDiagnostics(), ...program.getGlobalDiagnostics());
3668
+ const sources = program.getSourceFiles().filter(file => {
3669
+ const original = file.fileName.replace(/(\.vue)\.[cm]?[jt]sx?$/, '$1');
3670
+ return closure.has(path.resolve(original));
3671
+ });
3672
+ for (const file of sources) {
3673
+ diagnostics.push(...program.getSyntacticDiagnostics(file), ...program.getSemanticDiagnostics(file));
3674
+ if (!file.isDeclarationFile) {
3675
+ // 官方 emit 保留真实 props、重载和推导结果,绝不以手写接口或 any 代替。
3676
+ const emitted = program.emit(file, undefined, undefined, true);
3677
+ diagnostics.push(...emitted.diagnostics);
3678
+ if (emitted.emitSkipped) diagnostics.push({
3679
+ category: ts.DiagnosticCategory.Error, code: 90001,
3680
+ messageText: '暴露模块声明 emit 被编译器跳过:' + file.fileName,
3681
+ });
3682
+ }
3683
+ }
3684
+ }
3685
+ const errors = diagnostics.filter(diagnostic => diagnostic.category === ts.DiagnosticCategory.Error);
3686
+ if (errors.length) {
3687
+ process.stdout.write(ts.formatDiagnostics(errors, formatHost));
3688
+ process.exitCode = 1;
3689
+ }
3690
+ `;
3691
+ }
3692
+ var init_dts_vue_program = __esm({
3693
+ "src/dts-vue-program.ts"() {
3694
+ "use strict";
3695
+ }
3696
+ });
3697
+
3637
3698
  // src/dts-shared.ts
3638
3699
  function isSafeBundlePath(v) {
3639
3700
  if (typeof v !== "string" || v.length === 0) return false;
@@ -3928,7 +3989,9 @@ function loadTsContext(root, ts, diagnostics) {
3928
3989
  diagnostics.push(`tsconfig \u89E3\u6790\u5931\u8D25\uFF08${tsconfigFile}\uFF09\uFF1A${ts.flattenDiagnosticMessageText(raw.error.messageText, " ")}`);
3929
3990
  return null;
3930
3991
  }
3931
- const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path6.dirname(tsconfigFile));
3992
+ const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path6.dirname(tsconfigFile), void 0, void 0, void 0, [
3993
+ { extension: ".vue", isMixedContent: true, scriptKind: ts.ScriptKind.Deferred }
3994
+ ]);
3932
3995
  const co = { ...parsed.options };
3933
3996
  if (typeof co.baseUrl === "string" && !path6.isAbsolute(co.baseUrl)) {
3934
3997
  co.baseUrl = path6.resolve(path6.dirname(tsconfigFile), co.baseUrl);
@@ -4016,11 +4079,17 @@ async function generateTypesBundle(input) {
4016
4079
  const vueTscPkg = JSON.parse(fs6.readFileSync(path6.join(vueTscDir, "package.json"), "utf8"));
4017
4080
  const binRel = vueTscPkg.bin?.["vue-tsc"] ?? vueTscPkg.bin?.["vue-tsc.js"] ?? "bin/vue-tsc.js";
4018
4081
  const binPath = path6.resolve(vueTscDir, binRel);
4082
+ const scopedVueProgram = /^1\./.test(vueTscPkg.version);
4019
4083
  if (!fs6.existsSync(binPath)) {
4020
4084
  return { ok: false, diagnostics: [`vue-tsc \u5165\u53E3\u4E0D\u5B58\u5728\uFF08${binPath}\uFF09\u3002\u8BF7\u91CD\u65B0\u5B89\u88C5 vue-tsc\u3002`] };
4021
4085
  }
4022
- const tmpCfg = path6.join(root, `.fulgurjs-types-tsconfig-${process.pid}-${crypto.randomUUID()}.json`);
4023
- const outDir = fs6.mkdtempSync(path6.join(root, "node_modules", ".fulgurjs-types-emit-"));
4086
+ const cacheDir = input.incrementalDir;
4087
+ if (cacheDir) fs6.mkdirSync(cacheDir, { recursive: true });
4088
+ const tmpCfg = path6.join(root, `.fulgurjs-types-tsconfig-${cacheDir ? path6.basename(cacheDir) : `${process.pid}-${crypto.randomUUID()}`}.json`);
4089
+ const outDir = cacheDir ? path6.join(cacheDir, "emit") : fs6.mkdtempSync(path6.join(root, "node_modules", ".fulgurjs-types-emit-"));
4090
+ const clearOutput = () => {
4091
+ if (!cacheDir) fs6.rmSync(outDir, { recursive: true, force: true });
4092
+ };
4024
4093
  const baseCo = { ...rawOptionsWithInherited(ctx) };
4025
4094
  delete baseCo.noEmit;
4026
4095
  delete baseCo.incremental;
@@ -4031,6 +4100,7 @@ async function generateTypesBundle(input) {
4031
4100
  delete baseCo.extends;
4032
4101
  const resolvedTypeFiles = resolveTypesEntries(root, baseCo, diagnostics);
4033
4102
  fs6.writeFileSync(tmpCfg, JSON.stringify({
4103
+ ...ctx.tsconfigFile ? { extends: ctx.tsconfigFile } : {},
4034
4104
  compilerOptions: {
4035
4105
  ...baseCo,
4036
4106
  noEmit: false,
@@ -4042,7 +4112,8 @@ async function generateTypesBundle(input) {
4042
4112
  declarationMap: false,
4043
4113
  sourceMap: false,
4044
4114
  outDir,
4045
- rootDir
4115
+ rootDir,
4116
+ ...cacheDir && !scopedVueProgram ? { incremental: true, tsBuildInfoFile: path6.join(cacheDir, "state.tsbuildinfo") } : {}
4046
4117
  },
4047
4118
  include: [
4048
4119
  ...entryFiles.map((f) => path6.relative(root, f)),
@@ -4053,23 +4124,50 @@ async function generateTypesBundle(input) {
4053
4124
  if (process.env.FG_DUMP_TSCFG) fs6.writeFileSync(process.env.FG_DUMP_TSCFG, fs6.readFileSync(tmpCfg, "utf8"));
4054
4125
  const isOom = (text) => /(^|\n)\s*FATAL ERROR:.*(heap out of memory|Ineffective mark-compacts|Allocation failed)/i.test(text);
4055
4126
  const isSystemKilled = (e, out, errText) => !!e && (e.signal != null || /(^|\n)\s*(Killed|-9)\s*(:9)?\s*$/i.test(errText)) && !isOom(errText) && !/error TS\d+/i.test(out + "\n" + errText);
4127
+ const isTimeoutKill = (e) => !!e && e.killed === true && !/error TS\d+/i.test(String(e.message ?? ""));
4128
+ const timeoutFor = (raisedHeap) => {
4129
+ const env = Number(process.env.FG_DTS_TIMEOUT_MS);
4130
+ if (Number.isFinite(env) && env > 0) return env;
4131
+ return raisedHeap ? 30 * 60 * 1e3 : 10 * 60 * 1e3;
4132
+ };
4056
4133
  try {
4057
4134
  const attempt = (extraNodeArgs) => new Promise((resolve2) => {
4135
+ if (signal?.aborted) {
4136
+ resolve2({ err: Object.assign(new Error("\u58F0\u660E\u751F\u6210\u5DF2\u53D6\u6D88"), { code: "ABORT_ERR" }), stdout: "", stderr: "" });
4137
+ return;
4138
+ }
4058
4139
  const child = execFile(
4059
4140
  process.execPath,
4060
- [...extraNodeArgs, binPath, "-p", tmpCfg, "--noErrorTruncation", "--pretty", "false"],
4061
- { cwd: root, encoding: "utf8", maxBuffer: 64 * 1024 * 1024, timeout: 10 * 60 * 1e3 },
4062
- (err2, stdout2, stderr2) => resolve2({ err: err2 ?? null, stdout: String(stdout2 ?? ""), stderr: String(stderr2 ?? "") })
4141
+ [...extraNodeArgs, ...scopedVueProgram ? ["--eval", genVueDeclarationProgram(), tmpCfg, JSON.stringify([...closure])] : [binPath, "-p", tmpCfg, "--noErrorTruncation", "--pretty", "false"]],
4142
+ { cwd: root, encoding: "utf8", maxBuffer: 64 * 1024 * 1024, timeout: timeoutFor(extraNodeArgs.length > 0) },
4143
+ (err2, stdout2, stderr2) => {
4144
+ signal?.removeEventListener("abort", abort);
4145
+ resolve2({ err: err2 ?? null, stdout: String(stdout2 ?? ""), stderr: String(stderr2 ?? "") });
4146
+ }
4063
4147
  );
4064
- signal?.addEventListener("abort", () => child.kill("SIGKILL"), { once: true });
4148
+ const abort = () => {
4149
+ child.kill("SIGKILL");
4150
+ };
4151
+ signal?.addEventListener("abort", abort, { once: true });
4152
+ if (signal?.aborted) abort();
4065
4153
  });
4066
- let { err, stdout, stderr } = await attempt([]);
4154
+ const heapMarker = cacheDir ? path6.join(cacheDir, "raised-heap") : void 0;
4155
+ const raisedArgs = [`--max-old-space-size=${process.env.FG_DTS_MAX_OLD_SPACE ?? "8192"}`];
4156
+ const initialArgs = heapMarker && fs6.existsSync(heapMarker) ? raisedArgs : [];
4157
+ let { err, stdout, stderr } = await attempt(initialArgs);
4158
+ if (signal?.aborted) {
4159
+ clearOutput();
4160
+ return { ok: false, diagnostics: ["vue-tsc \u58F0\u660E\u751F\u6210\u88AB\u4E2D\u6B62\uFF08dev server \u5173\u95ED\uFF09\u3002"] };
4161
+ }
4067
4162
  if (err && isOom(stderr)) {
4068
4163
  const raised = process.env.FG_DTS_MAX_OLD_SPACE ?? "8192";
4069
- diagnostics.push(`vue-tsc \u58F0\u660E\u751F\u6210\u5728\u9ED8\u8BA4\u5806\u4E0B\u5185\u5B58\u4E0D\u8DB3\uFF08V8 OOM\uFF09\uFF0C\u4EE5 --max-old-space-size=${raised}MB \u91CD\u8BD5\u3002`);
4070
- ({ err, stdout, stderr } = await attempt([`--max-old-space-size=${raised}`]));
4164
+ if (initialArgs.length === 0) {
4165
+ diagnostics.push(`vue-tsc \u58F0\u660E\u751F\u6210\u5728\u9ED8\u8BA4\u5806\u4E0B\u5185\u5B58\u4E0D\u8DB3\uFF08V8 OOM\uFF09\uFF0C\u4EE5 --max-old-space-size=${raised}MB \u91CD\u8BD5\u3002`);
4166
+ if (heapMarker) fs6.writeFileSync(heapMarker, "");
4167
+ ({ err, stdout, stderr } = await attempt([`--max-old-space-size=${raised}`]));
4168
+ }
4071
4169
  if (err && isOom(stderr)) {
4072
- fs6.rmSync(outDir, { recursive: true, force: true });
4170
+ clearOutput();
4073
4171
  diagnostics.push(
4074
4172
  "vue-tsc \u58F0\u660E\u751F\u6210\u5185\u5B58\u4E0D\u8DB3\uFF08\u63D0\u9AD8\u5806\u540E\u4ECD OOM\uFF09\u2014\u2014\u7C7B\u578B\u8D44\u6E90\u672A\u4EA7\u51FA\u3002",
4075
4173
  "\u4FEE\u6CD5\uFF1A\u7528\u73AF\u5883\u53D8\u91CF FG_DTS_MAX_OLD_SPACE \u63D0\u9AD8\u751F\u6210\u5668\u5806\uFF08\u5982 16384\uFF09\uFF0C\u6216\u7F29\u5C0F\u66B4\u9732\u6A21\u5757\u7684\u9759\u6001\u4F9D\u8D56\u9762\u540E\u91CD\u8BD5\u3002"
@@ -4077,11 +4175,24 @@ async function generateTypesBundle(input) {
4077
4175
  return { ok: false, diagnostics };
4078
4176
  }
4079
4177
  }
4080
- if (err && isSystemKilled(err, stdout, stderr)) {
4178
+ if (err && isTimeoutKill(err) && !isOom(stderr)) {
4179
+ const raised = process.env.FG_DTS_MAX_OLD_SPACE ?? "8192";
4180
+ diagnostics.push(`vue-tsc \u58F0\u660E\u751F\u6210\u8D85\u8FC7\u5355\u6B21\u4E0A\u9650\uFF08${Math.round(timeoutFor(false) / 6e4)} \u5206\u949F\uFF09\u88AB\u5F3A\u6740\uFF0C\u4EE5\u63D0\u5806 + \u66F4\u957F\u4E0A\u9650\u91CD\u8BD5\u3002`);
4181
+ ({ err, stdout, stderr } = await attempt([`--max-old-space-size=${raised}`]));
4182
+ if (err && isTimeoutKill(err) && !isOom(stderr) && !/error TS\d+/i.test(stdout + "\n" + stderr)) {
4183
+ clearOutput();
4184
+ diagnostics.push(
4185
+ `vue-tsc \u58F0\u660E\u751F\u6210\u518D\u6B21\u8D85\u65F6\uFF08\u5355\u6B21\u4E0A\u9650 ${Math.round(timeoutFor(true) / 6e4)} \u5206\u949F\uFF09\u2014\u2014\u7C7B\u578B\u8D44\u6E90\u672A\u4EA7\u51FA\u3002`,
4186
+ "\u4FEE\u6CD5\uFF1A\u7528\u73AF\u5883\u53D8\u91CF FG_DTS_TIMEOUT_MS \u63D0\u9AD8\u4E0A\u9650\uFF08\u6BEB\u79D2\uFF0C\u5982 3600000\uFF09\uFF0C\u6216\u7F29\u5C0F\u66B4\u9732\u6A21\u5757\u7684\u9759\u6001\u4F9D\u8D56\u9762\u3002"
4187
+ );
4188
+ return { ok: false, diagnostics };
4189
+ }
4190
+ }
4191
+ if (err && isSystemKilled(err, stdout, stderr) && !isTimeoutKill(err)) {
4081
4192
  diagnostics.push(`vue-tsc \u58F0\u660E\u751F\u6210\u8FDB\u7A0B\u88AB\u7CFB\u7EDF\u7EC8\u6B62\uFF08signal=${err.signal ?? "Killed"}\uFF0C\u65E0 TypeScript \u8BCA\u65AD\u8F93\u51FA\uFF09\uFF0C\u91CD\u8BD5\u4E00\u6B21\u3002`);
4082
4193
  ({ err, stdout, stderr } = await attempt([]));
4083
- if (err && isSystemKilled(err, stdout, stderr)) {
4084
- fs6.rmSync(outDir, { recursive: true, force: true });
4194
+ if (err && isSystemKilled(err, stdout, stderr) && !isTimeoutKill(err)) {
4195
+ clearOutput();
4085
4196
  diagnostics.push(
4086
4197
  "vue-tsc \u58F0\u660E\u751F\u6210\u8FDB\u7A0B\u518D\u6B21\u88AB\u7CFB\u7EDF\u7EC8\u6B62\u2014\u2014\u7C7B\u578B\u8D44\u6E90\u672A\u4EA7\u51FA\u3002",
4087
4198
  "\u5E38\u89C1\u539F\u56E0\uFF1A\u673A\u5668\u5185\u5B58\u538B\u529B\u4E0B\u88AB OS \u7EC8\u6B62\uFF08\u5982\u540C\u65F6\u8FD0\u884C\u591A\u4E2A\u5927\u578B\u58F0\u660E\u751F\u6210/\u6784\u5EFA\uFF09\uFF0C\u6216\u8FDB\u7A0B\u88AB\u5916\u90E8 kill\u3002",
@@ -4093,7 +4204,7 @@ async function generateTypesBundle(input) {
4093
4204
  if (err) {
4094
4205
  if (signal?.aborted) {
4095
4206
  diagnostics.push("vue-tsc \u58F0\u660E\u751F\u6210\u88AB\u4E2D\u6B62\uFF08dev server \u5173\u95ED\uFF09\u3002");
4096
- fs6.rmSync(outDir, { recursive: true, force: true });
4207
+ clearOutput();
4097
4208
  return { ok: false, diagnostics };
4098
4209
  }
4099
4210
  const errFiles = parseErrorFiles(stdout, root);
@@ -4103,19 +4214,19 @@ async function generateTypesBundle(input) {
4103
4214
  const tail = formatDeclarationDiagnostics(stdout, stderr, err.message, root, closure);
4104
4215
  diagnostics.push(`vue-tsc \u58F0\u660E\u751F\u6210\u5931\u8D25\uFF08\u66B4\u9732\u95ED\u5305\u5185\u5B58\u5728\u7F16\u8BD1\u9519\u8BEF\uFF09\u2014\u2014\u7C7B\u578B\u8D44\u6E90\u672A\u4EA7\u51FA\uFF1A
4105
4216
  ${tail}`);
4106
- fs6.rmSync(outDir, { recursive: true, force: true });
4217
+ clearOutput();
4107
4218
  return { ok: false, diagnostics };
4108
4219
  }
4109
4220
  }
4110
4221
  } catch {
4111
- fs6.rmSync(outDir, { recursive: true, force: true });
4222
+ clearOutput();
4112
4223
  fs6.rmSync(tmpCfg, { force: true });
4113
4224
  return { ok: false, diagnostics };
4114
4225
  } finally {
4115
4226
  fs6.rmSync(tmpCfg, { force: true });
4116
4227
  }
4117
4228
  collectEmitted(ts, outDir, rootDir, emitted, closure);
4118
- fs6.rmSync(outDir, { recursive: true, force: true });
4229
+ clearOutput();
4119
4230
  } else {
4120
4231
  const outDir = fs6.mkdtempSync(path6.join(root, "node_modules", ".fulgurjs-types-emit-"));
4121
4232
  const program = ts.createProgram([...entryFiles, ...ctx.ambientInputs, ...resolveTypesEntries(root, ctx.rawOptions, [])], {
@@ -4340,6 +4451,7 @@ var init_dts_generate = __esm({
4340
4451
  "src/dts-generate.ts"() {
4341
4452
  "use strict";
4342
4453
  init_dts_diagnostics();
4454
+ init_dts_vue_program();
4343
4455
  init_dts_shared();
4344
4456
  INHERITABLE_KEYS = [
4345
4457
  "paths",