openxiangda 1.0.0 → 1.0.2
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/package.json +1 -1
- package/packages/sdk/dist/build/index.cjs +0 -4
- package/packages/sdk/dist/components/index.cjs +32325 -2724
- package/packages/sdk/dist/components/index.cjs.map +1 -1
- package/packages/sdk/dist/components/index.css +5313 -0
- package/packages/sdk/dist/components/index.css.map +1 -0
- package/packages/sdk/dist/components/index.mjs +31203 -2424
- package/packages/sdk/dist/components/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/index.cjs +64 -36
- package/packages/sdk/dist/runtime/index.cjs.map +1 -1
- package/packages/sdk/dist/runtime/index.mjs +64 -20
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/styles/antd-theme.cjs +0 -4
- package/packages/sdk/src/build-source/scripts/build-forms.mjs +141 -39
- package/packages/sdk/src/build-source/scripts/build-pages.mjs +44 -9
- package/packages/sdk/src/build-source/scripts/build-workspace.mjs +27 -2
- package/packages/sdk/src/build-source/scripts/utils/incremental.mjs +13 -3
- package/packages/sdk/src/build-source/src/cli.mjs +43 -4
|
@@ -30,6 +30,7 @@ const runtimeDistDir = path.join(rootDir, "dist/form-runtime");
|
|
|
30
30
|
const tmpDir = path.join(rootDir, ".tmp");
|
|
31
31
|
const runtimeVersionPlaceholder = "__SY_FORM_RUNTIME_VERSION__";
|
|
32
32
|
const runtimeCacheFileName = "build-cache.json";
|
|
33
|
+
const portalContainerResolverGlobal = "__OPENXIANGDA_GET_PORTAL_CONTAINER__";
|
|
33
34
|
|
|
34
35
|
const runtimePackages = [
|
|
35
36
|
"react",
|
|
@@ -164,7 +165,6 @@ function parseArgs(argv) {
|
|
|
164
165
|
}
|
|
165
166
|
if (arg === "--force") {
|
|
166
167
|
result.force = true;
|
|
167
|
-
result.runtimeCache = false;
|
|
168
168
|
continue;
|
|
169
169
|
}
|
|
170
170
|
if (arg === "--dry-run") {
|
|
@@ -196,7 +196,7 @@ build-forms - 构建表单页面
|
|
|
196
196
|
选项:
|
|
197
197
|
--form <name> 只构建指定表单(src/forms/ 下的目录名)
|
|
198
198
|
--only <list> 只构建指定模块,如 forms/customer,pages/dashboard
|
|
199
|
-
--force
|
|
199
|
+
--force 忽略增量缓存,强制重建表单产物
|
|
200
200
|
--dry-run 只打印增量计划,不构建
|
|
201
201
|
--clean-cache 删除 .openxiangda/build-cache.json
|
|
202
202
|
--no-runtime-cache 强制重建共享 runtime
|
|
@@ -237,11 +237,16 @@ import { App as AntdApp, ConfigProvider } from 'antd';
|
|
|
237
237
|
import zhCN from 'antd/locale/zh_CN';
|
|
238
238
|
import * as SyFormComponentsModule from 'openxiangda';
|
|
239
239
|
import { antdTheme } from 'openxiangda/antd-theme';
|
|
240
|
+
import 'antd-mobile/es/global';
|
|
240
241
|
import '../src/index.css';
|
|
241
242
|
|
|
242
243
|
const runtimeVersion = '${runtimeVersionPlaceholder}';
|
|
243
244
|
const roots = new WeakMap();
|
|
245
|
+
const portalContainerCleanups = new WeakMap();
|
|
244
246
|
const { StandardFormPage, defineFormSchema } = SyFormComponentsModule;
|
|
247
|
+
const NAMESPACE_ROOT_CLASS = 'sy-app-workspace';
|
|
248
|
+
const PORTAL_CONTAINER_STACK_GLOBAL = '__OPENXIANGDA_PORTAL_CONTAINER_STACK__';
|
|
249
|
+
const PORTAL_CONTAINER_RESOLVER_GLOBAL = '${portalContainerResolverGlobal}';
|
|
245
250
|
|
|
246
251
|
function getStyleContainer(el) {
|
|
247
252
|
const rootNode = el.getRootNode?.();
|
|
@@ -250,58 +255,115 @@ function getStyleContainer(el) {
|
|
|
250
255
|
: document.head;
|
|
251
256
|
}
|
|
252
257
|
|
|
253
|
-
function getNamespaceRoot(el) {
|
|
254
|
-
return el.closest?.('.sy-app-workspace') || el;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
258
|
function isInShadowRoot(el) {
|
|
258
259
|
const rootNode = el.getRootNode?.();
|
|
259
260
|
return typeof ShadowRoot !== 'undefined' && rootNode instanceof ShadowRoot;
|
|
260
261
|
}
|
|
261
262
|
|
|
263
|
+
function getNamespaceRoot(el, triggerNode) {
|
|
264
|
+
if (isInShadowRoot(el)) return el;
|
|
265
|
+
const triggerRoot = triggerNode?.closest?.('.' + NAMESPACE_ROOT_CLASS);
|
|
266
|
+
return (
|
|
267
|
+
triggerRoot ||
|
|
268
|
+
el.closest?.('.' + NAMESPACE_ROOT_CLASS) ||
|
|
269
|
+
el.querySelector?.('.' + NAMESPACE_ROOT_CLASS) ||
|
|
270
|
+
el
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
262
274
|
function getPopupContainer(el) {
|
|
263
|
-
|
|
264
|
-
return (triggerNode) => {
|
|
265
|
-
if (inShadowRoot) return el;
|
|
266
|
-
return getNamespaceRoot(el) || triggerNode?.parentElement || document.body;
|
|
267
|
-
};
|
|
275
|
+
return (triggerNode) => getNamespaceRoot(el, triggerNode);
|
|
268
276
|
}
|
|
269
277
|
|
|
270
278
|
function getTargetContainer(el) {
|
|
271
|
-
return () =>
|
|
279
|
+
return () => getNamespaceRoot(el);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function createAntdConfig(el) {
|
|
283
|
+
return {
|
|
284
|
+
locale: zhCN,
|
|
285
|
+
prefixCls: 'sy-ant',
|
|
286
|
+
iconPrefixCls: 'sy-anticon',
|
|
287
|
+
theme: antdTheme,
|
|
288
|
+
getPopupContainer: getPopupContainer(el),
|
|
289
|
+
getTargetContainer: getTargetContainer(el),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function installRuntimePortalContainer(el) {
|
|
294
|
+
const stack = Array.isArray(globalThis[PORTAL_CONTAINER_STACK_GLOBAL])
|
|
295
|
+
? globalThis[PORTAL_CONTAINER_STACK_GLOBAL]
|
|
296
|
+
: [];
|
|
297
|
+
stack.push(el);
|
|
298
|
+
globalThis[PORTAL_CONTAINER_STACK_GLOBAL] = stack;
|
|
299
|
+
globalThis[PORTAL_CONTAINER_RESOLVER_GLOBAL] = () => {
|
|
300
|
+
for (let index = stack.length - 1; index >= 0; index -= 1) {
|
|
301
|
+
const candidate = stack[index];
|
|
302
|
+
if (candidate?.isConnected) {
|
|
303
|
+
return getNamespaceRoot(candidate);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return document.querySelector('.' + NAMESPACE_ROOT_CLASS) || document.body;
|
|
307
|
+
};
|
|
308
|
+
return () => {
|
|
309
|
+
const position = stack.lastIndexOf(el);
|
|
310
|
+
if (position >= 0) stack.splice(position, 1);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function installAntdStaticHolder(el) {
|
|
315
|
+
ConfigProvider.config({
|
|
316
|
+
prefixCls: 'sy-ant',
|
|
317
|
+
iconPrefixCls: 'sy-anticon',
|
|
318
|
+
theme: antdTheme,
|
|
319
|
+
holderRender: (children) => {
|
|
320
|
+
if (!el.isConnected) {
|
|
321
|
+
return (
|
|
322
|
+
<ConfigProvider prefixCls="sy-ant" iconPrefixCls="sy-anticon" theme={antdTheme}>
|
|
323
|
+
{children}
|
|
324
|
+
</ConfigProvider>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
return (
|
|
328
|
+
<StyleProvider hashPriority="high" container={getStyleContainer(el)}>
|
|
329
|
+
<ConfigProvider {...createAntdConfig(el)}>{children}</ConfigProvider>
|
|
330
|
+
</StyleProvider>
|
|
331
|
+
);
|
|
332
|
+
},
|
|
333
|
+
});
|
|
272
334
|
}
|
|
273
335
|
|
|
274
336
|
function renderStandardForm(el, schemaInput, context = {}) {
|
|
275
337
|
let root = roots.get(el);
|
|
338
|
+
el.classList.add(NAMESPACE_ROOT_CLASS);
|
|
339
|
+
if (!portalContainerCleanups.has(el)) {
|
|
340
|
+
portalContainerCleanups.set(el, installRuntimePortalContainer(el));
|
|
341
|
+
}
|
|
342
|
+
installAntdStaticHolder(el);
|
|
276
343
|
if (!root) {
|
|
277
|
-
if (!isInShadowRoot(el)) el.classList.add('sy-app-workspace');
|
|
278
344
|
root = createRoot(el);
|
|
279
345
|
roots.set(el, root);
|
|
280
346
|
}
|
|
281
347
|
|
|
282
348
|
const schema = defineFormSchema(schemaInput);
|
|
349
|
+
const antdConfig = createAntdConfig(el);
|
|
283
350
|
root.render(
|
|
284
351
|
<StyleProvider hashPriority="high" container={getStyleContainer(el)}>
|
|
285
|
-
<ConfigProvider
|
|
286
|
-
locale={zhCN}
|
|
287
|
-
prefixCls="sy-ant"
|
|
288
|
-
iconPrefixCls="sy-anticon"
|
|
289
|
-
theme={antdTheme}
|
|
290
|
-
getPopupContainer={getPopupContainer(el)}
|
|
291
|
-
getTargetContainer={getTargetContainer(el)}
|
|
292
|
-
>
|
|
352
|
+
<ConfigProvider {...antdConfig}>
|
|
293
353
|
<AntdApp>
|
|
294
|
-
<
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
354
|
+
<div className="sy-app-workspace">
|
|
355
|
+
<StandardFormPage
|
|
356
|
+
schema={schema}
|
|
357
|
+
mode={context.mode || 'submit'}
|
|
358
|
+
initialValues={context.initialValues}
|
|
359
|
+
permissions={context.permissions}
|
|
360
|
+
formUuid={context.formUuid}
|
|
361
|
+
appType={context.appType}
|
|
362
|
+
formInstanceId={context.formInstanceId}
|
|
363
|
+
onSubmit={context.onSubmit}
|
|
364
|
+
inDrawer={context.inDrawer}
|
|
365
|
+
/>
|
|
366
|
+
</div>
|
|
305
367
|
</AntdApp>
|
|
306
368
|
</ConfigProvider>
|
|
307
369
|
</StyleProvider>
|
|
@@ -314,6 +376,11 @@ function unmountStandardForm(el) {
|
|
|
314
376
|
root.unmount();
|
|
315
377
|
roots.delete(el);
|
|
316
378
|
}
|
|
379
|
+
const releasePortalContainer = portalContainerCleanups.get(el);
|
|
380
|
+
if (releasePortalContainer) {
|
|
381
|
+
releasePortalContainer();
|
|
382
|
+
portalContainerCleanups.delete(el);
|
|
383
|
+
}
|
|
317
384
|
}
|
|
318
385
|
|
|
319
386
|
export function createStandardFormModule(schemaInput) {
|
|
@@ -355,6 +422,24 @@ export default formRuntime;
|
|
|
355
422
|
`;
|
|
356
423
|
}
|
|
357
424
|
|
|
425
|
+
function createAntdMobilePortalPatchPlugin() {
|
|
426
|
+
const resolverExpression = `globalThis.${portalContainerResolverGlobal}?.() || document.body`;
|
|
427
|
+
return {
|
|
428
|
+
name: "openxiangda-antd-mobile-portal-container",
|
|
429
|
+
transform(code, id) {
|
|
430
|
+
if (!id.includes("/antd-mobile/") && !id.includes("\\\\antd-mobile\\\\")) {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
const nextCode = code.replace(
|
|
434
|
+
/getContainer:\s*\(\)\s*=>\s*document\.body/g,
|
|
435
|
+
`getContainer: () => ${resolverExpression}`,
|
|
436
|
+
);
|
|
437
|
+
if (nextCode === code) return null;
|
|
438
|
+
return { code: nextCode, map: null };
|
|
439
|
+
},
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
358
443
|
function createFormRuntimeProxyPlugin() {
|
|
359
444
|
return {
|
|
360
445
|
name: "sy-form-runtime-proxy",
|
|
@@ -546,7 +631,7 @@ async function buildSharedRuntime(options = {}) {
|
|
|
546
631
|
},
|
|
547
632
|
},
|
|
548
633
|
},
|
|
549
|
-
plugins: [reactPlugin],
|
|
634
|
+
plugins: [createAntdMobilePortalPatchPlugin(), reactPlugin],
|
|
550
635
|
logLevel: "warn",
|
|
551
636
|
});
|
|
552
637
|
|
|
@@ -688,7 +773,11 @@ async function buildForm(form) {
|
|
|
688
773
|
},
|
|
689
774
|
},
|
|
690
775
|
},
|
|
691
|
-
plugins: [
|
|
776
|
+
plugins: [
|
|
777
|
+
createAntdMobilePortalPatchPlugin(),
|
|
778
|
+
createFormRuntimeProxyPlugin(),
|
|
779
|
+
reactPlugin,
|
|
780
|
+
].filter(Boolean),
|
|
692
781
|
logLevel: "warn",
|
|
693
782
|
});
|
|
694
783
|
|
|
@@ -751,9 +840,14 @@ async function main() {
|
|
|
751
840
|
const startedAt = Date.now();
|
|
752
841
|
console.log("[build] 构建表单页面");
|
|
753
842
|
console.log("[build] 构建模式: shared runtime");
|
|
754
|
-
const
|
|
755
|
-
const
|
|
756
|
-
|
|
843
|
+
const onlyTargets = normalizeOnly(args.only);
|
|
844
|
+
const only = onlyTargets.filter((item) => item.startsWith("forms/"));
|
|
845
|
+
if (onlyTargets.length > 0 && only.length === 0) {
|
|
846
|
+
console.log("[build] forms: No form targets selected");
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const requested = args.form ? [`forms/${args.form}`] : only;
|
|
850
|
+
const forms = discoverForms("");
|
|
757
851
|
|
|
758
852
|
if (forms.length === 0) {
|
|
759
853
|
if (args.form) {
|
|
@@ -763,16 +857,24 @@ async function main() {
|
|
|
763
857
|
}
|
|
764
858
|
process.exit(1);
|
|
765
859
|
}
|
|
860
|
+
const formKeys = new Set(forms.map((form) => form.key));
|
|
861
|
+
const missing = requested.filter((key) => !formKeys.has(key));
|
|
862
|
+
if (missing.length > 0) {
|
|
863
|
+
console.error(
|
|
864
|
+
`错误: 找不到表单 ${missing.map((key) => `"${key.slice("forms/".length)}"`).join(", ")}`,
|
|
865
|
+
);
|
|
866
|
+
process.exit(1);
|
|
867
|
+
}
|
|
766
868
|
|
|
767
869
|
const plan = planIncrementalBuild(forms, {
|
|
768
870
|
force: args.force,
|
|
769
|
-
only:
|
|
871
|
+
only: requested.length ? requested : undefined,
|
|
770
872
|
});
|
|
771
873
|
printPlan(plan, "forms");
|
|
772
874
|
if (args.dryRun) return;
|
|
773
875
|
if (plan.changed.length === 0) return;
|
|
774
876
|
|
|
775
|
-
if (plan.fullRebuild &&
|
|
877
|
+
if (plan.fullRebuild && requested.length === 0 && fs.existsSync(distDir)) {
|
|
776
878
|
fs.rmSync(distDir, { recursive: true, force: true });
|
|
777
879
|
}
|
|
778
880
|
|
|
@@ -34,12 +34,14 @@ const tmpDir = path.join(rootDir, ".tmp");
|
|
|
34
34
|
const runtimeDistDir = path.join(distRoot, "page-runtime");
|
|
35
35
|
const runtimeVersionPlaceholder = "__SY_PAGE_RUNTIME_VERSION__";
|
|
36
36
|
const runtimeCacheFileName = "build-cache.json";
|
|
37
|
+
const portalContainerResolverGlobal = "__OPENXIANGDA_GET_PORTAL_CONTAINER__";
|
|
37
38
|
|
|
38
39
|
const runtimePackages = [
|
|
39
40
|
"react",
|
|
40
41
|
"react-dom",
|
|
41
42
|
"@ant-design/cssinjs",
|
|
42
43
|
"antd",
|
|
44
|
+
"antd-mobile",
|
|
43
45
|
"@ant-design/icons",
|
|
44
46
|
"openxiangda",
|
|
45
47
|
];
|
|
@@ -163,7 +165,6 @@ function parseArgs(argv) {
|
|
|
163
165
|
}
|
|
164
166
|
if (arg === "--force") {
|
|
165
167
|
result.force = true;
|
|
166
|
-
result.runtimeCache = false;
|
|
167
168
|
continue;
|
|
168
169
|
}
|
|
169
170
|
if (arg === "--dry-run") {
|
|
@@ -194,7 +195,7 @@ build-pages - 构建复杂代码页
|
|
|
194
195
|
选项:
|
|
195
196
|
--page <name> 只构建指定页面目录
|
|
196
197
|
--only <list> 只构建指定模块,如 forms/customer,pages/dashboard
|
|
197
|
-
--force
|
|
198
|
+
--force 忽略增量缓存,强制重建页面产物
|
|
198
199
|
--dry-run 只打印增量计划,不构建
|
|
199
200
|
--clean-cache 删除 .openxiangda/build-cache.json
|
|
200
201
|
--no-runtime-cache 强制重建共享 runtime
|
|
@@ -339,6 +340,24 @@ async function createCssOptions() {
|
|
|
339
340
|
};
|
|
340
341
|
}
|
|
341
342
|
|
|
343
|
+
function createAntdMobilePortalPatchPlugin() {
|
|
344
|
+
const resolverExpression = `globalThis.${portalContainerResolverGlobal}?.() || document.body`;
|
|
345
|
+
return {
|
|
346
|
+
name: "openxiangda-antd-mobile-portal-container",
|
|
347
|
+
transform(code, id) {
|
|
348
|
+
if (!id.includes("/antd-mobile/") && !id.includes("\\\\antd-mobile\\\\")) {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
const nextCode = code.replace(
|
|
352
|
+
/getContainer:\s*\(\)\s*=>\s*document\.body/g,
|
|
353
|
+
`getContainer: () => ${resolverExpression}`,
|
|
354
|
+
);
|
|
355
|
+
if (nextCode === code) return null;
|
|
356
|
+
return { code: nextCode, map: null };
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
342
361
|
function createResolveAlias() {
|
|
343
362
|
return [
|
|
344
363
|
{
|
|
@@ -373,7 +392,7 @@ async function buildSharedRuntime(options = {}) {
|
|
|
373
392
|
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
374
393
|
"process.env": JSON.stringify({ NODE_ENV: "production" }),
|
|
375
394
|
},
|
|
376
|
-
plugins: [react()],
|
|
395
|
+
plugins: [createAntdMobilePortalPatchPlugin(), react()],
|
|
377
396
|
resolve: {
|
|
378
397
|
alias: createResolveAlias(),
|
|
379
398
|
dedupe: ["react", "react-dom", "antd", "@ant-design/cssinjs"],
|
|
@@ -655,7 +674,11 @@ async function buildPage(page) {
|
|
|
655
674
|
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
656
675
|
"process.env": JSON.stringify({ NODE_ENV: "production" }),
|
|
657
676
|
},
|
|
658
|
-
plugins: [
|
|
677
|
+
plugins: [
|
|
678
|
+
createAntdMobilePortalPatchPlugin(),
|
|
679
|
+
createSharedRuntimeProxyPlugin(),
|
|
680
|
+
react(),
|
|
681
|
+
],
|
|
659
682
|
resolve: {
|
|
660
683
|
alias: createResolveAlias(),
|
|
661
684
|
dedupe: ["react", "react-dom", "antd", "@ant-design/cssinjs"],
|
|
@@ -731,9 +754,14 @@ async function main() {
|
|
|
731
754
|
return;
|
|
732
755
|
}
|
|
733
756
|
|
|
734
|
-
const
|
|
735
|
-
const
|
|
736
|
-
|
|
757
|
+
const onlyTargets = normalizeOnly(args.only);
|
|
758
|
+
const only = onlyTargets.filter((item) => item.startsWith("pages/"));
|
|
759
|
+
if (onlyTargets.length > 0 && only.length === 0) {
|
|
760
|
+
console.log("[build] pages: No page targets selected");
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
const requested = args.page ? [`pages/${args.page}`] : only;
|
|
764
|
+
const pages = (await discoverPages("")).map((page) => ({
|
|
737
765
|
...page,
|
|
738
766
|
key: `pages/${page.dirName}`,
|
|
739
767
|
dirPath: page.dirPath,
|
|
@@ -745,16 +773,23 @@ async function main() {
|
|
|
745
773
|
console.log("未发现复杂代码页,跳过 pages 构建");
|
|
746
774
|
return;
|
|
747
775
|
}
|
|
776
|
+
const pageKeys = new Set(pages.map((page) => page.key));
|
|
777
|
+
const missing = requested.filter((key) => !pageKeys.has(key));
|
|
778
|
+
if (missing.length > 0) {
|
|
779
|
+
throw new Error(
|
|
780
|
+
`找不到代码页 ${missing.map((key) => `"${key.slice("pages/".length)}"`).join(", ")}`,
|
|
781
|
+
);
|
|
782
|
+
}
|
|
748
783
|
|
|
749
784
|
const plan = planIncrementalBuild(pages, {
|
|
750
785
|
force: args.force,
|
|
751
|
-
only:
|
|
786
|
+
only: requested.length ? requested : undefined,
|
|
752
787
|
});
|
|
753
788
|
printPlan(plan, "pages");
|
|
754
789
|
if (args.dryRun) return;
|
|
755
790
|
if (plan.changed.length === 0) return;
|
|
756
791
|
|
|
757
|
-
if (plan.fullRebuild &&
|
|
792
|
+
if (plan.fullRebuild && requested.length === 0) {
|
|
758
793
|
await fs.rm(path.join(distRoot, "pages"), { recursive: true, force: true });
|
|
759
794
|
}
|
|
760
795
|
await fs.mkdir(tmpDir, { recursive: true });
|
|
@@ -3,12 +3,14 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { rootDir } from "./utils/load-config.mjs";
|
|
6
|
+
import { normalizeOnly } from "./utils/incremental.mjs";
|
|
6
7
|
|
|
7
8
|
const require = createRequire(import.meta.url);
|
|
8
9
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
9
10
|
const tsxCli = require.resolve("tsx/cli");
|
|
10
11
|
const args = process.argv.slice(2).filter((arg) => arg !== "--");
|
|
11
12
|
const forwardedArgs = [];
|
|
13
|
+
const onlyValues = [];
|
|
12
14
|
|
|
13
15
|
if (args.includes("--help") || args.includes("-h")) {
|
|
14
16
|
console.log(`
|
|
@@ -35,13 +37,32 @@ for (let index = 0; index < args.length; index += 1) {
|
|
|
35
37
|
}
|
|
36
38
|
if (arg === "--only" && args[index + 1]) {
|
|
37
39
|
forwardedArgs.push(arg, args[index + 1]);
|
|
40
|
+
onlyValues.push(args[index + 1]);
|
|
38
41
|
index += 1;
|
|
39
42
|
}
|
|
40
43
|
if (arg.startsWith("--only=")) {
|
|
41
44
|
forwardedArgs.push(arg);
|
|
45
|
+
onlyValues.push(arg.slice("--only=".length));
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
const onlyTargets = normalizeOnly(onlyValues);
|
|
50
|
+
const invalidOnlyTargets = onlyTargets.filter(
|
|
51
|
+
(item) => !item.startsWith("forms/") && !item.startsWith("pages/"),
|
|
52
|
+
);
|
|
53
|
+
if (invalidOnlyTargets.length > 0) {
|
|
54
|
+
console.error(
|
|
55
|
+
`[build] --only 目标必须以 forms/ 或 pages/ 开头: ${invalidOnlyTargets.join(", ")}`,
|
|
56
|
+
);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const hasOnlyTargets = onlyTargets.length > 0;
|
|
61
|
+
const shouldBuildForms =
|
|
62
|
+
!hasOnlyTargets || onlyTargets.some((item) => item.startsWith("forms/"));
|
|
63
|
+
const shouldBuildPages =
|
|
64
|
+
!hasOnlyTargets || onlyTargets.some((item) => item.startsWith("pages/"));
|
|
65
|
+
|
|
45
66
|
const runScript = (scriptName, args) =>
|
|
46
67
|
new Promise((resolve, reject) => {
|
|
47
68
|
const child = spawn(process.execPath, [tsxCli, path.join(scriptDir, scriptName), ...args], {
|
|
@@ -60,5 +81,9 @@ const runScript = (scriptName, args) =>
|
|
|
60
81
|
});
|
|
61
82
|
});
|
|
62
83
|
|
|
63
|
-
|
|
64
|
-
await runScript("build-
|
|
84
|
+
if (shouldBuildForms) {
|
|
85
|
+
await runScript("build-forms.mjs", forwardedArgs);
|
|
86
|
+
}
|
|
87
|
+
if (shouldBuildPages) {
|
|
88
|
+
await runScript("build-pages.mjs", forwardedArgs);
|
|
89
|
+
}
|
|
@@ -172,6 +172,10 @@ export function commitIncrementalBuild(plan, builtModules) {
|
|
|
172
172
|
const previous = loadBuildCache();
|
|
173
173
|
const entries = { ...(previous?.entries || {}) };
|
|
174
174
|
const now = new Date().toISOString();
|
|
175
|
+
const isPartialBuild = plan.selected.length !== plan.all.length;
|
|
176
|
+
const preserveGlobalSnapshot = Boolean(
|
|
177
|
+
previous && isPartialBuild && plan.fullRebuild,
|
|
178
|
+
);
|
|
175
179
|
for (const item of builtModules) {
|
|
176
180
|
entries[item.key] = {
|
|
177
181
|
contentHash: plan.snapshot.moduleHashes[item.key],
|
|
@@ -185,9 +189,15 @@ export function commitIncrementalBuild(plan, builtModules) {
|
|
|
185
189
|
`${JSON.stringify(
|
|
186
190
|
{
|
|
187
191
|
version: CACHE_VERSION,
|
|
188
|
-
lockfileHash:
|
|
189
|
-
|
|
190
|
-
|
|
192
|
+
lockfileHash: preserveGlobalSnapshot
|
|
193
|
+
? previous.lockfileHash
|
|
194
|
+
: plan.snapshot.lockfileHash,
|
|
195
|
+
sharedHash: preserveGlobalSnapshot
|
|
196
|
+
? previous.sharedHash
|
|
197
|
+
: plan.snapshot.sharedHash,
|
|
198
|
+
configHash: preserveGlobalSnapshot
|
|
199
|
+
? previous.configHash
|
|
200
|
+
: plan.snapshot.configHash,
|
|
191
201
|
entries,
|
|
192
202
|
},
|
|
193
203
|
null,
|
|
@@ -63,6 +63,34 @@ const ignoredDirs = new Set([
|
|
|
63
63
|
const runtimePackages = ["openxiangda"];
|
|
64
64
|
const runtimePackageRegistry =
|
|
65
65
|
process.env.APP_WORKSPACE_NPM_REGISTRY || "https://registry.npmjs.org/";
|
|
66
|
+
const legacyTemplateTiptapOverrideVersion = "3.23.6";
|
|
67
|
+
const legacyTemplateTiptapOverrideKeys = new Set([
|
|
68
|
+
"@tiptap/core",
|
|
69
|
+
"@tiptap/pm",
|
|
70
|
+
"@tiptap/react",
|
|
71
|
+
"@tiptap/starter-kit",
|
|
72
|
+
"@tiptap/extensions",
|
|
73
|
+
"@tiptap/extension-list",
|
|
74
|
+
"@tiptap/extension-blockquote",
|
|
75
|
+
"@tiptap/extension-bold",
|
|
76
|
+
"@tiptap/extension-bubble-menu",
|
|
77
|
+
"@tiptap/extension-bullet-list",
|
|
78
|
+
"@tiptap/extension-character-count",
|
|
79
|
+
"@tiptap/extension-code",
|
|
80
|
+
"@tiptap/extension-document",
|
|
81
|
+
"@tiptap/extension-floating-menu",
|
|
82
|
+
"@tiptap/extension-hard-break",
|
|
83
|
+
"@tiptap/extension-heading",
|
|
84
|
+
"@tiptap/extension-horizontal-rule",
|
|
85
|
+
"@tiptap/extension-italic",
|
|
86
|
+
"@tiptap/extension-list-item",
|
|
87
|
+
"@tiptap/extension-list-keymap",
|
|
88
|
+
"@tiptap/extension-ordered-list",
|
|
89
|
+
"@tiptap/extension-paragraph",
|
|
90
|
+
"@tiptap/extension-placeholder",
|
|
91
|
+
"@tiptap/extension-strike",
|
|
92
|
+
"@tiptap/extension-text",
|
|
93
|
+
]);
|
|
66
94
|
|
|
67
95
|
function usage() {
|
|
68
96
|
return `
|
|
@@ -150,6 +178,19 @@ function writeJson(path, value) {
|
|
|
150
178
|
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
|
|
151
179
|
}
|
|
152
180
|
|
|
181
|
+
function getLegacyTemplateTiptapOverrideKeys(overrides = {}) {
|
|
182
|
+
const tiptapKeys = Object.keys(overrides).filter((key) =>
|
|
183
|
+
key.startsWith("@tiptap/"),
|
|
184
|
+
);
|
|
185
|
+
if (tiptapKeys.length === 0) return [];
|
|
186
|
+
const isLegacyTemplateSet = tiptapKeys.every(
|
|
187
|
+
(key) =>
|
|
188
|
+
legacyTemplateTiptapOverrideKeys.has(key) &&
|
|
189
|
+
overrides[key] === legacyTemplateTiptapOverrideVersion,
|
|
190
|
+
);
|
|
191
|
+
return isLegacyTemplateSet ? tiptapKeys : [];
|
|
192
|
+
}
|
|
193
|
+
|
|
153
194
|
function escapeRegExp(value) {
|
|
154
195
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
155
196
|
}
|
|
@@ -298,10 +339,8 @@ function updatePackageJson(workspaceRoot, channel) {
|
|
|
298
339
|
}
|
|
299
340
|
}
|
|
300
341
|
if (pkg.pnpm?.overrides) {
|
|
301
|
-
for (const key of
|
|
302
|
-
|
|
303
|
-
delete pkg.pnpm.overrides[key];
|
|
304
|
-
}
|
|
342
|
+
for (const key of getLegacyTemplateTiptapOverrideKeys(pkg.pnpm.overrides)) {
|
|
343
|
+
delete pkg.pnpm.overrides[key];
|
|
305
344
|
}
|
|
306
345
|
if (Object.keys(pkg.pnpm.overrides).length === 0) {
|
|
307
346
|
delete pkg.pnpm.overrides;
|