Procházet zdrojové kódy

feat(material): optimize variable selector dependencies (#792)

* feat: tree shaking dependency to code editor

* feat: remove tsup config in form-materials

* feat: import on demand in form-materials
Yiwei Mao před 4 měsíci
rodič
revize
a99d476b66

+ 2 - 1
apps/demo-vite/package.json

@@ -47,7 +47,8 @@
     "cross-env": "~7.0.3",
     "cross-env": "~7.0.3",
     "globals": "^15.11.0",
     "globals": "^15.11.0",
     "less": "^4.1.2",
     "less": "^4.1.2",
-    "vite": "^6.3.5"
+    "vite": "^6.3.5",
+    "vite-bundle-analyzer": "~1.2.3"
   },
   },
   "publishConfig": {
   "publishConfig": {
     "access": "public",
     "access": "public",

+ 4 - 5
apps/demo-vite/src/hooks/use-editor-props.tsx

@@ -14,7 +14,7 @@ import {
   Field,
   Field,
   useNodeRender,
   useNodeRender,
 } from '@flowgram.ai/free-layout-editor';
 } from '@flowgram.ai/free-layout-editor';
-import { CodeEditor } from '@flowgram.ai/form-materials';
+import { VariableSelector } from '@flowgram.ai/form-materials/components/variable-selector';
 
 
 import { nodeRegistries } from '../node-registries';
 import { nodeRegistries } from '../node-registries';
 import { initialData } from '../initial-data';
 import { initialData } from '../initial-data';
@@ -59,12 +59,11 @@ export const useEditorProps = () =>
                 <Field<string> name="title">
                 <Field<string> name="title">
                   {({ field }) => <div className="demo-free-node-title">{field.value}</div>}
                   {({ field }) => <div className="demo-free-node-title">{field.value}</div>}
                 </Field>
                 </Field>
-                <Field<string> name="code">
+                <Field<string[]> name="code">
                   {({ field }) => (
                   {({ field }) => (
-                    <CodeEditor
-                      languageId="typescript"
+                    <VariableSelector
                       value={field.value}
                       value={field.value}
-                      onChange={field.onChange}
+                      onChange={(value) => field.onChange(value || [])}
                     />
                     />
                   )}
                   )}
                 </Field>
                 </Field>

+ 13 - 4
apps/demo-vite/tsconfig.json

@@ -9,15 +9,24 @@
     "strictPropertyInitialization": false,
     "strictPropertyInitialization": false,
     "strict": true,
     "strict": true,
     "esModuleInterop": true,
     "esModuleInterop": true,
-    "moduleResolution": "node",
+    "moduleResolution": "bundler",
     "skipLibCheck": true,
     "skipLibCheck": true,
     "noUnusedLocals": true,
     "noUnusedLocals": true,
     "noImplicitAny": true,
     "noImplicitAny": true,
     "allowJs": true,
     "allowJs": true,
     "resolveJsonModule": true,
     "resolveJsonModule": true,
-    "types": ["node"],
+    "types": [
+      "node"
+    ],
     "jsx": "react-jsx",
     "jsx": "react-jsx",
-    "lib": ["es6", "dom", "es2020", "es2019.Array"]
+    "lib": [
+      "es6",
+      "dom",
+      "es2020",
+      "es2019.Array"
+    ]
   },
   },
-  "include": ["./src"],
+  "include": [
+    "./src"
+  ],
 }
 }

+ 2 - 1
apps/demo-vite/vite.config.js

@@ -5,10 +5,11 @@
 
 
 import { defineConfig } from 'vite';
 import { defineConfig } from 'vite';
 import react from '@vitejs/plugin-react';
 import react from '@vitejs/plugin-react';
+import { analyzer } from 'vite-bundle-analyzer';
 
 
 // https://vite.dev/config/
 // https://vite.dev/config/
 export default defineConfig({
 export default defineConfig({
-  plugins: [react()],
+  plugins: [react(), analyzer()],
   server: {
   server: {
     fs: {
     fs: {
       strict: false,
       strict: false,

+ 8 - 0
common/config/rush/pnpm-lock.yaml

@@ -808,6 +808,9 @@ importers:
       vite:
       vite:
         specifier: ^6.3.5
         specifier: ^6.3.5
         version: 6.3.5(@types/node@18.19.68)(less@4.3.0)
         version: 6.3.5(@types/node@18.19.68)(less@4.3.0)
+      vite-bundle-analyzer:
+        specifier: ~1.2.3
+        version: 1.2.3
 
 
   ../../apps/docs:
   ../../apps/docs:
     dependencies:
     dependencies:
@@ -19730,6 +19733,11 @@ packages:
       vfile-message: 4.0.2
       vfile-message: 4.0.2
     dev: false
     dev: false
 
 
+  /vite-bundle-analyzer@1.2.3:
+    resolution: {integrity: sha512-8nhwDGHWMKKgg6oegAOpDgTT7/yzTVzeYzLF4y8WBJoYu9gO7h29UpHiQnXD2rAvfQzDy5Wqe/Za5cgqhnxi5g==}
+    hasBin: true
+    dev: true
+
   /vite-node@0.34.6(@types/node@18.19.68):
   /vite-node@0.34.6(@types/node@18.19.68):
     resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
     resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
     engines: {node: '>=v14.18.0'}
     engines: {node: '>=v14.18.0'}

+ 41 - 3
packages/materials/form-materials/package.json

@@ -5,13 +5,51 @@
   "repository": "https://github.com/bytedance/flowgram.ai",
   "repository": "https://github.com/bytedance/flowgram.ai",
   "license": "MIT",
   "license": "MIT",
   "exports": {
   "exports": {
-    "types": "./dist/types/index.d.ts",
-    "import": "./dist/esm/index.mjs",
-    "require": "./dist/cjs/index.js"
+    ".": {
+      "types": "./dist/types/index.d.ts",
+      "import": "./dist/esm/index.mjs",
+      "require": "./dist/cjs/index.js"
+    },
+    "./components/*": {
+      "types": "./dist/types/components/*/index.d.ts",
+      "import": "./dist/esm/components/*/index.mjs",
+      "require": "./dist/cjs/components/*/index.js"
+    },
+    "./effects/*": {
+      "types": "./dist/types/effects/*/index.d.ts",
+      "import": "./dist/esm/effects/*/index.mjs",
+      "require": "./dist/cjs/effects/*/index.js"
+    },
+    "./hooks/*": {
+      "types": "./dist/types/hooks/*/index.d.ts",
+      "import": "./dist/esm/hooks/*/index.mjs",
+      "require": "./dist/cjs/hooks/*/index.js"
+    },
+    "./shared/*": {
+      "types": "./dist/types/shared/*/index.d.ts",
+      "import": "./dist/esm/shared/*/index.mjs",
+      "require": "./dist/cjs/shared/*/index.js"
+    },
+    "./form-plugins/*": {
+      "types": "./dist/types/form-plugins/*/index.d.ts",
+      "import": "./dist/esm/form-plugins/*/index.mjs",
+      "require": "./dist/cjs/form-plugins/*/index.js"
+    },
+    "./plugins/*": {
+      "types": "./dist/types/plugins/*/index.d.ts",
+      "import": "./dist/esm/plugins/*/index.mjs",
+      "require": "./dist/cjs/plugins/*/index.js"
+    },
+    "./validate/*": {
+      "types": "./dist/types/validate/*/index.d.ts",
+      "import": "./dist/esm/validate/*/index.mjs",
+      "require": "./dist/cjs/validate/*/index.js"
+    }
   },
   },
   "main": "./dist/cjs/index.js",
   "main": "./dist/cjs/index.js",
   "module": "./dist/esm/index.mjs",
   "module": "./dist/esm/index.mjs",
   "types": "./dist/types/index.d.ts",
   "types": "./dist/types/index.d.ts",
+  "sideEffects": false,
   "bin": {
   "bin": {
     "flowgram-form-materials": "./bin/run.sh"
     "flowgram-form-materials": "./bin/run.sh"
   },
   },

+ 6 - 4
packages/materials/form-materials/src/components/display-schema-tree/index.tsx

@@ -5,9 +5,11 @@
 
 
 import React from 'react';
 import React from 'react';
 
 
-import { IJsonSchema, JsonSchemaTypeManager } from '@flowgram.ai/json-schema';
-
-import { useTypeManager } from '@/plugins';
+import {
+  type IJsonSchema,
+  type JsonSchemaTypeManager,
+  useTypeManager,
+} from '@flowgram.ai/json-schema';
 
 
 import { HorizontalLine, TreeItem, TreeLevel, TreeRow, TreeTitle } from './styles';
 import { HorizontalLine, TreeItem, TreeLevel, TreeRow, TreeTitle } from './styles';
 
 
@@ -33,7 +35,7 @@ function SchemaTree(props: PropsType) {
     parentKey = '',
     parentKey = '',
   } = props || {};
   } = props || {};
 
 
-  const typeManager = useTypeManager();
+  const typeManager = useTypeManager() as JsonSchemaTypeManager;
 
 
   const config = typeManager.getTypeBySchema(schema);
   const config = typeManager.getTypeBySchema(schema);
   const title = typeManager.getComplexText(schema);
   const title = typeManager.getComplexText(schema);

+ 2 - 3
packages/materials/form-materials/src/components/type-selector/index.tsx

@@ -5,11 +5,10 @@
 
 
 import React, { useMemo } from 'react';
 import React, { useMemo } from 'react';
 
 
-import { IJsonSchema } from '@flowgram.ai/json-schema';
+import { IJsonSchema, useTypeManager, JsonSchemaTypeManager } from '@flowgram.ai/json-schema';
 import { Cascader, Icon, IconButton } from '@douyinfe/semi-ui';
 import { Cascader, Icon, IconButton } from '@douyinfe/semi-ui';
 
 
 import { createInjectMaterial } from '@/shared/inject-material';
 import { createInjectMaterial } from '@/shared/inject-material';
-import { useTypeManager } from '@/plugins';
 
 
 export interface TypeSelectorProps {
 export interface TypeSelectorProps {
   value?: Partial<IJsonSchema>;
   value?: Partial<IJsonSchema>;
@@ -47,7 +46,7 @@ export function TypeSelector(props: TypeSelectorProps) {
 
 
   const selectValue = useMemo(() => getTypeSelectValue(value), [value]);
   const selectValue = useMemo(() => getTypeSelectValue(value), [value]);
 
 
-  const typeManager = useTypeManager();
+  const typeManager = useTypeManager() as JsonSchemaTypeManager;
 
 
   const icon = typeManager.getDisplayIcon(value || {});
   const icon = typeManager.getDisplayIcon(value || {});
 
 

+ 2 - 2
packages/materials/form-materials/src/components/variable-selector/index.tsx

@@ -7,8 +7,8 @@ import React, { useMemo } from 'react';
 
 
 import { IJsonSchema } from '@flowgram.ai/json-schema';
 import { IJsonSchema } from '@flowgram.ai/json-schema';
 import { I18n } from '@flowgram.ai/editor';
 import { I18n } from '@flowgram.ai/editor';
-import { TriggerRenderProps } from '@douyinfe/semi-ui/lib/es/treeSelect';
-import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
+import { type TriggerRenderProps } from '@douyinfe/semi-ui/lib/es/treeSelect';
+import { type TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
 import { Popover } from '@douyinfe/semi-ui';
 import { Popover } from '@douyinfe/semi-ui';
 import { IconChevronDownStroked, IconIssueStroked } from '@douyinfe/semi-icons';
 import { IconChevronDownStroked, IconIssueStroked } from '@douyinfe/semi-icons';
 
 

+ 7 - 4
packages/materials/form-materials/src/components/variable-selector/use-variable-tree.tsx

@@ -5,13 +5,16 @@
 
 
 import React, { useCallback } from 'react';
 import React, { useCallback } from 'react';
 
 
-import { IJsonSchema, JsonSchemaUtils } from '@flowgram.ai/json-schema';
+import {
+  IJsonSchema,
+  JsonSchemaTypeManager,
+  JsonSchemaUtils,
+  useTypeManager,
+} from '@flowgram.ai/json-schema';
 import { ASTMatch, BaseVariableField, useAvailableVariables } from '@flowgram.ai/editor';
 import { ASTMatch, BaseVariableField, useAvailableVariables } from '@flowgram.ai/editor';
 import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
 import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
 import { Icon } from '@douyinfe/semi-ui';
 import { Icon } from '@douyinfe/semi-ui';
 
 
-import { useTypeManager } from '@/plugins';
-
 type VariableField = BaseVariableField<{
 type VariableField = BaseVariableField<{
   icon?: string | JSX.Element;
   icon?: string | JSX.Element;
   title?: string;
   title?: string;
@@ -25,7 +28,7 @@ export function useVariableTree(params: {
 }): TreeNodeData[] {
 }): TreeNodeData[] {
   const { includeSchema, excludeSchema, skipVariable } = params;
   const { includeSchema, excludeSchema, skipVariable } = params;
 
 
-  const typeManager = useTypeManager();
+  const typeManager = useTypeManager() as JsonSchemaTypeManager;
   const variables = useAvailableVariables();
   const variables = useAvailableVariables();
 
 
   const getVariableTypeIcon = useCallback((variable: VariableField) => {
   const getVariableTypeIcon = useCallback((variable: VariableField) => {

+ 4 - 20
packages/materials/form-materials/src/plugins/json-schema-preset/index.tsx

@@ -2,33 +2,17 @@
  * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  * SPDX-License-Identifier: MIT
  * SPDX-License-Identifier: MIT
  */
  */
-import React from 'react';
 
 
 import {
 import {
-  type IJsonSchema,
-  JsonSchemaUtils,
-  useTypeManager as useOriginTypeManager,
-  TypePresetProvider as OriginTypePresetProvider,
-  JsonSchemaTypeManager,
   type JsonSchemaBasicType,
   type JsonSchemaBasicType,
+  JsonSchemaUtils,
+  type IJsonSchema,
 } from '@flowgram.ai/json-schema';
 } from '@flowgram.ai/json-schema';
 
 
-import { jsonSchemaTypePreset } from './type-definition';
-import { type JsonSchemaTypeRegistry, type ConstantRendererProps } from './manager';
+import { useTypeManager, JsonSchemaTypePresetProvider } from './react';
+import { ConstantRendererProps, type JsonSchemaTypeRegistry } from './manager';
 import { createTypePresetPlugin } from './create-type-preset-plugin';
 import { createTypePresetPlugin } from './create-type-preset-plugin';
 
 
-const useTypeManager = () =>
-  useOriginTypeManager() as JsonSchemaTypeManager<IJsonSchema, JsonSchemaTypeRegistry>;
-
-const JsonSchemaTypePresetProvider = ({
-  types = [],
-  children,
-}: React.PropsWithChildren<{ types: JsonSchemaTypeRegistry[] }>) => (
-  <OriginTypePresetProvider types={[...jsonSchemaTypePreset, ...types]}>
-    {children}
-  </OriginTypePresetProvider>
-);
-
 export {
 export {
   createTypePresetPlugin,
   createTypePresetPlugin,
   useTypeManager,
   useTypeManager,

+ 28 - 0
packages/materials/form-materials/src/plugins/json-schema-preset/react.tsx

@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+ * SPDX-License-Identifier: MIT
+ */
+
+import React from 'react';
+
+import {
+  type IJsonSchema,
+  useTypeManager as useOriginTypeManager,
+  TypePresetProvider as OriginTypePresetProvider,
+  JsonSchemaTypeManager,
+} from '@flowgram.ai/json-schema';
+
+import { jsonSchemaTypePreset } from './type-definition';
+import { type JsonSchemaTypeRegistry } from './manager';
+
+export const useTypeManager = () =>
+  useOriginTypeManager() as JsonSchemaTypeManager<IJsonSchema, JsonSchemaTypeRegistry>;
+
+export const JsonSchemaTypePresetProvider = ({
+  types = [],
+  children,
+}: React.PropsWithChildren<{ types: JsonSchemaTypeRegistry[] }>) => (
+  <OriginTypePresetProvider types={[...jsonSchemaTypePreset, ...types]}>
+    {children}
+  </OriginTypePresetProvider>
+);

+ 1 - 2
packages/materials/form-materials/src/validate/validate-flow-value/index.tsx

@@ -6,8 +6,7 @@
 import { isNil } from 'lodash-es';
 import { isNil } from 'lodash-es';
 import { FeedbackLevel, FlowNodeEntity, getNodeScope } from '@flowgram.ai/editor';
 import { FeedbackLevel, FlowNodeEntity, getNodeScope } from '@flowgram.ai/editor';
 
 
-import { IFlowValue } from '@/shared';
-import { FlowValueUtils } from '@/shared';
+import { type IFlowValue, FlowValueUtils } from '@/shared';
 
 
 interface Context {
 interface Context {
   node: FlowNodeEntity;
   node: FlowNodeEntity;

+ 0 - 11
packages/materials/form-materials/tsup.config.js

@@ -1,11 +0,0 @@
-/**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
-
-import { defineConfig } from 'tsup';
-
-export default defineConfig({
-  // https://tsup.egoist.dev/#inject-cjs-and-esm-shims
-  shims: true,
-});