Bytebase Schema Editor 前端架构迁移:从 Vue 3 到 React 的增量迁移定义与设计
【免费下载链接】bytebaseDatabase governance built for humans and agents — controlling changes and access across every major database.项目地址: https://gitcode.com/GitHub_Trending/by/bytebase
本文以 Bytebase 仓库内
docs/plans/2026-04-16-schema-editor-react-migration/definition.md为骨架,结合同目录设计文档(design.md、plan.md)与仓库实际落地代码(frontend/src/modules/schema-editor/),系统阐述 Bytebase 中最复杂的交互面之一——可视化 Schema Editor——从 Vue 3 迁移到 React 的背景、现状盘点、非目标约束、开放决策与分阶段实施路径。读完本文,你将理解大规模前端框架增量迁移中"界定迁移边界、识别可复用纯 TS 层、以共存策略保障零回归"的完整方法论,并看到该方案在仓库中的真实落地形态。
一、背景与上下文:Bytebase 前端的 Vue→React 渐进式迁移
Bytebase 的前端正在经历一场从 Vue 3 到 React 的增量迁移(incremental migration)。在编写本迁移定义时,仓库中已经存在一批 React 页面——ProjectDatabaseDetailPage、ProjectSyncSchemaPage、IssueDetailPage——它们通过useVueState()桥接进入 Vue 的 store,并复用 Vue 层中纯 TypeScript 编写的工具函数。这一过程由一个统一的迁移手册(React Migration Playbook)约束,核心原则有三条:
- 迁移有边界的界面(migrate bounded surfaces);
- 复用已有的 store 与工具函数,不为迁移而重写基础设施;
- 只有在调用方全部消失后才删除 Vue 文件。
该 playbook 同时沉淀了迁移中的工程纪律:路由边界处通过ReactPageMount.vue挂载 React 页面并传入规范化 props;Monaco 等命令式库统一收敛到一个稳定的集成接缝(shared helper)而非在 React effect 中直接动态 import;React 页面默认继续走 Pinia store 与 Connect 栈,只有出现具体问题(如 React 自有共享 UI 状态、请求缓存)才引入 zustand 或 TanStack Query。
Schema Editor 迁移正是这一体系下规模最大、耦合最深的子项目。
二、问题陈述:为什么 Schema Editor 是一个高难度的迁移对象
Schema Editor 是产品中最复杂的交互面之一。它提供:
- 可视化 DDL 编辑:表(tables)、列(columns)、索引(indexes)、分区(partitions)、视图(views)、存储过程(procedures)、函数(functions);
- ER 图查看器(ER diagram viewer);
- SQL 编辑器侧边栏的 schema 浏览器(schema browser)。
它通过 Plan/Issue 流程中编辑数据库变更规格(change specifications)的入口访问;ER 图和 schema 面板则用于数据库详情页与 SQL 编辑器视图。
问题的核心在于:SchemaEditorLite 组件套件(88 个文件、约 10,300 行)、SchemaDiagram 组件套件(44 个文件、约 2,300 行)以及 SchemaPane 侧边栏(36+ 种树节点类型、约 1,700 行)全部由 Vue 3 实现,并重度依赖 naive-ui、Vue 的 provide/inject 上下文以及 Emittery 事件总线——这些在 React 生态中没有对等物。目前 React 页面嵌入 schema 编辑或可视化时,要么使用 Vue 桥接包装器,要么只导入叶子工具函数(例如getColumnDefaultValuePlaceholder)。仓库中不存在任何 React 版本的 schema 编辑器、关系图或 schema 面板实现——这正是本次迁移要填补的空白。
三、当前状态盘点:三大 Vue 组件套件的结构与规模
3.1 SchemaEditorLite(frontend/src/components/SchemaEditorLite/)
注:该路径为定义文档写作时的 Vue 实现位置;迁移落地后的 React 实现位于
frontend/src/modules/schema-editor/(详见第六节)。
SchemaEditorLite 是编辑器主体,入口为SchemaEditorLite.vue(144 行),采用 naive-uiNSplit双栏布局:左侧为树(aside tree)+ 右侧为编辑器面板。整体 88 个文件、约 10,300 行,内部按职责分为若干层:
面板层(Panels,约 1,300 行)
| 文件 | 行数 | 职责 |
|---|---|---|
DatabaseEditor.vue | 284 | 数据库级编辑:schema 选择、表列表、建表入口 |
TableEditor.vue | 480 | 表级编辑:列/索引/分区多模式切换 |
TableList.vue | 327 | 表列表展示与操作 |
ViewEditor.vue | 103 | 视图 SQL 定义编辑 |
FunctionEditor.vue/ProcedureEditor.vue | 70 / 70 | 函数/存储过程编辑 |
PreviewPane.vue | 144 | DDL diff 预览 |
CommonCodeEditor.vue | 67 | Monaco 公共封装 |
列单元格组件(TableColumnEditor/,约 370 行):DataTypeCell.vue(99)、DefaultValueCell.vue(64)、ForeignKeyCell.vue(100)、OperationCell.vue、ReorderCell.vue、SelectionCell.vue。
专项编辑器:IndexesEditor/(133 行)、PartitionsEditor/(248 行)。
模态框(Modals,约 1,069 行):ActionConfirmModal.vue(59)、TableNameModal.vue(177)、SchemaNameModal.vue(105)、EditColumnForeignKeyModal.vue(287)、ViewNameModal.vue(142)、FunctionNameModal.vue(150)、ProcedureNameModal.vue(149)。
树导航(Aside/Tree):Tree.vue使用 naive-uiNTree,具备虚拟滚动、右键菜单与 10+ 种节点复选框变体(约 390 行)。
上下文层(context/,约 1,267 行):provideSchemaEditorContext()通过 Emittery 事件总线组合四个子 hook——useTabs()(131)、useEditStatus()(237)、useSelection()(628)、useScrollStatus()(113)。这是整个编辑器状态管理的枢纽。
算法层(algorithm/,约 979 行):diff-merge.ts(790 行)承担嵌套元数据(nested metadata)的比较与调和;rebuild.ts(39 行)、apply.ts(77 行)。
类型与能力声明:types.ts(107 行)定义EditTarget、TabContext(database/table/view/procedure/function 变体)、EditStatus、RolloutObject;spec.ts导出引擎级功能支持谓词,例如engineSupportsEditIndexes、engineSupportsEditTablePartitions。
公共 API(index.ts):导出 types、common、spec、utils、context、edit、ActionConfirmModal、TableColumnEditor与默认导出SchemaEditorLite。
3.2 SchemaDiagram(frontend/src/components/SchemaDiagram/)
ER 图查看器,44 个文件、约 2,300 行。入口SchemaDiagram.vue(265 行)包含导航器(navigator)、画布、表节点与外键连线:
- Canvas:SVG 视口支持平移/缩放(
useDragCanvas、useFitView、useSetCenter); - ER 布局:
TableNode.vue(228)、ForeignKeyLine.vue,以及基于 ELK 的自动布局引擎(autoLayout/engines/elk.ts,70 行); - 几何工具(约 750 行):面向点、矩形、线段相交的 2D 数学计算。
3.3 SchemaPane(frontend/src/views/sql-editor/AsidePanel/SchemaPane/)
SQL 编辑器侧边栏的 schema 浏览器,约 1,735 行:
- 36+ 种树节点类型(
TreeNode/):CommonNode.vue以及 database/schema/table/view/procedure/function/index/trigger/sequence/partition 等专用节点; - HoverPanel/:
TableInfo.vue、ColumnInfo.vue、ViewInfo.vue等悬停信息卡; - 工具模块:
tree.ts(由元数据构建树)、click.ts(路由跳转)、hover-state.ts、actions.tsx(右键菜单)。
3.4 集成点(Vue 调用方)
SchemaEditorLite 被多个 Vue 界面嵌入:
Plan/components/StatementSection/SchemaEditorDrawer.vue——以抽屉形式包装 SchemaEditorLite 用于 Plan SQL 编辑;Plan/components/StatementSection/EditorView/EditorView.vue——触发 SchemaEditorDrawer;sql-editor/EditorPanel/Panels/TablesPanel/ColumnsTable.vue——导入DefaultValueCell、ForeignKeyCell;sql-editor/EditorPanel/Panels/ViewsPanel/ColumnsTable.vue与ExternalTablesPanel/ExternalTableColumnsTable.vue——导入DefaultValueCell;sql-editor/EditorPanel/DiagramPanel——使用 SchemaDiagram;DatabaseDetail/SchemaDiagramButton.vue——SchemaDiagram 的模态查看器;ColumnDataTable/index.vue与sql-editor/AsidePanel/SchemaPane/HoverPanel/ColumnInfo.vue——导入getColumnDefaultValuePlaceholder。
3.5 已触及 schema 工具的 React 代码
React 侧目前只触及叶子工具:react/pages/project/database-detail/overview/DatabaseObjectExplorer.tsx从SchemaEditorLite/utils/columnDefaultValue导入getColumnDefaultValuePlaceholder。
3.6 可复用的 React UI 原语
frontend/src/react/components/ui/已提供:dialog.tsx、sheet.tsx、alert-dialog.tsx、tabs.tsx、table.tsx、button.tsx、combobox.tsx、search-input.tsx、input.tsx、dropdown-menu.tsx、separator.tsx、tooltip.tsx、badge.tsx、switch.tsx、radio-group.tsx、textarea.tsx——这是 React 版编辑器"零新增重型 UI 库"的底气所在。
3.7 Vue 实现的关键外部依赖
- naive-ui:
NTree(虚拟滚动)、NSplit(可拖拽分栏)、NButton、NSelect、NDropdown、NModal; - Emittery:上下文通信事件总线(6 种事件类型);
- lodash-es:
cloneDeep、isEqual、debounce; - ELK(elkjs):ER 图布局;
- Monaco Editor:SQL 代码编辑(经包装器);
- Proto-ES 类型:
DatabaseMetadata、SchemaMetadata、TableMetadata、ColumnMetadata、ViewMetadata、ProcedureMetadata、FunctionMetadata。
四、非目标:迁移的边界约束
定义文档明确划定了迁移的"红线",防止范围蔓延:
- 不重写
algorithm/层(diff-merge、rebuild、apply)——纯 TypeScript、无 Vue 依赖,React 组件可直接导入; - 不重写
spec.ts与utils/——纯 TS 函数、引擎能力谓词与列默认值辅助函数原样可用; - 不重写
types.ts——类型定义与框架无关; - 不迁移 Plan/Issue 页面本身——schema 编辑器作为 React 组件被嵌入,父级 Vue 页面通过桥接使用;
- 不迁移 SQL 编辑器视图(TablesPanel、ViewsPanel、ExternalTablesPanel)——它们是各自有调用方的独立 Vue 界面;
- 不替换 ELK 布局引擎或 Monaco 编辑器集成——它们是与框架无关的库;
- 不引入新的状态管理库(zustand、TanStack Query),除非出现具体问题;
- 迁移期间不改变 schema 编辑器行为、不新增功能;
- 不迁移旧组件的全部 Vue 调用方——尚未迁移到 React 的 Vue 调用方继续使用 Vue 实现,直到它们自身被迁移。
五、开放问题:迁移中的关键决策点
定义文档记录了 5 个在迁移启动时必须拍板的问题(均附默认答案):
- React SchemaEditorLite 是全局替换 Vue 版,还是共存?(默认:共存——React 版服务 React 父组件,Vue 父组件在迁移完成前继续用 Vue 版);
- naive-ui 的虚拟滚动 NTree 用什么替代?(默认:用
react-window或 headless 树库自建轻量虚拟树,评估@tanstack/react-virtual); - naive-ui 的 NSplit 可拖拽分栏用什么替代?(默认:
react-resizable-panels或基于 CSS resize 的最小实现); - Emittery 事件总线是替换为 React Context + 回调,还是保留原样?(默认:替换为 React Context + 回调——Emittery 虽与框架无关,但事件驱动模式在 React 中不惯用);
- SchemaDiagram 与 SchemaPane 是否与 SchemaEditorLite 同批迁移?(默认:分开——它们是调用方不同的独立界面,SchemaEditorLite 是首要目标)。
六、范围评估:L 级子系统迁移
本迁移被评定为L(Large)级:跨越 88+ 个文件、约 10,300 行相互关联的 Vue 组件、上下文提供者与事件驱动状态管理。树导航、Tab 管理、编辑追踪、选择状态与面板渲染之间存在深度耦合。替换 Vue 特有模式(provide/inject、Emittery、NTree 虚拟滚动、NSplit 分栏)存在多种可行方案。其中算法/类型/工具层(约 1,200 行)可直接复用,但其余约 9,100 行的 UI 与状态管理需要跨约 70 个组件文件进行 React 重写。
七、目标架构:React 等价物如何替换 Vue 特有模式
配套设计文档(design.md)给出了完整的替代映射,核心思路是:React Context 替换 provide/inject 与 Emittery;headless 组件库替换 naive-ui;纯 TS 层原样复用。
7.1 组件树:React SchemaEditorLite 的目标结构
SchemaEditorLite (React Context provider + react-resizable-panels) ├── AsideTree (react-arborist + 自定义节点渲染器) │ ├── 节点渲染器 (database, schema, table, view, procedure, function) │ ├── 节点复选框 (选择状态) │ └── 右键菜单 (ui/ 的 dropdown-menu) ├── EditorPanel (基于 tab 类型的路由) │ ├── DatabaseEditor │ ├── TableEditor │ │ ├── TableColumnEditor (ui/ 的 table + 可编辑单元格) │ │ │ ├── DataTypeCell (combobox) │ │ │ ├── DefaultValueCell (input) │ │ │ ├── ForeignKeyCell (按钮 + 模态触发) │ │ │ ├── OperationCell │ │ │ ├── ReorderCell (拖拽手柄) │ │ │ └── SelectionCell (复选框) │ │ ├── IndexesEditor │ │ └── PartitionsEditor │ ├── ViewEditor (Monaco 封装) │ ├── ProcedureEditor (Monaco 封装) │ ├── FunctionEditor (Monaco 封装) │ └── PreviewPane (Monaco 封装, DDL diff 输出) └── Modals ├── TableNameModal (dialog) ├── SchemaNameModal (dialog) ├── EditColumnForeignKeyModal (sheet, 宽) ├── ViewNameModal (dialog) ├── FunctionNameModal (dialog) ├── ProcedureNameModal (dialog) └── ActionConfirmModal (alert-dialog)7.2 状态管理:React Context 替换 provide/inject + Emittery
Vue 的provideSchemaEditorContext组合了四个子 hook(useTabs、useEditStatus、useSelection、useScrollStatus)与一个 Emittery 事件总线。React 版使用单一 Context Provider,通过 hook 暴露同样的组合状态。
为什么选 React Context 而不是 zustand/TanStack:schema 编辑器的状态作用域限定于编辑器实例,并非全局状态。React Context 天然把状态限定在组件子树内,与 Vue provide/inject 模式完全对应;引入 zustand 等于为组件局部关注点引入全局状态(对应设计目标 4:遵循既有 React 模式)。
Emittery 六事件 → React 回调映射:
| Emittery 事件 | React 等价物 |
|---|---|
update:selected-rollout-objects | onSelectedRolloutObjectsChangeprop(提升至父组件) |
rebuild-tree | context 上的rebuildTree()函数,组件直接调用 |
rebuild-edit-status | context 上的rebuildEditStatus(resets) |
clear-tabs | context 上的clearTabs()(属于 tabs hook) |
refresh-preview | context 上的refreshPreview() |
merge-metadata | context 上的mergeMetadata(metadatas) |
Context Provider 形态为:SchemaEditorProvider创建组合 hook 的 context,子组件通过useSchemaEditorContext()消费。四个子 hook 分别用useState/useReducer/useRef/useMemo/useCallback重写,Vue→React 的映射是直接的:ref()→useState()、computed()→useMemo()、watch()→useEffect()。
7.3 可拖拽分栏:react-resizable-panels 替换 NSplit
Vue 版NSplit使用min=0.15、max=0.4、default-size=0.25。React 等价物:
PanelGroup (direction="horizontal") Panel (defaultSize=25, minSize=15, maxSize=40) → AsideTree PanelResizeHandle Panel (defaultSize=75) → EditorPanel选型理由:react-resizable-panels 是 headless/无样式(契合 shadcn 风格)、广泛采用、支持 WAI-ARIA 无障碍,且 shadcn 生态已对其封装,无需覆盖任何自带样式。
7.4 树导航:react-arborist 替换 NTree
react-arborist 提供虚拟化渲染(可承载 10,000+ 节点)、自定义节点渲染器、键盘导航与 ARIA、选择状态管理,直接对标 naive-uiNTree+ 虚拟滚动模式。
- 右键菜单:用
@/react/components/ui/的dropdown-menu在右键时触发,菜单项(建表、重命名、删除等)按节点类型决定,对齐 Vuecontext-menu.ts的逻辑; - 节点复选框:Vue 中 10+ 种复选框变体简化为单个
NodeCheckbox组件,接收节点元数据类型并委托给选择上下文——Vue 的变体多源于模板组合需拆文件,React 的 JSX 条件渲染可在单组件内完成。
7.5 Tab 管理与编辑器面板
- useTabs:Vue 用
Map<string, TabContext>+ 当前 tab 追踪;React 用useReducer,动作包括ADD_TAB、CLOSE_TAB、SET_CURRENT_TAB、CLEAR_TABS,tab 列表用@/react/components/ui/tabs渲染; - EditorPanel 路由:读取 context 中
currentTab.type,分发到 DatabaseEditor、TableEditor、ViewEditor、ProcedureEditor、FunctionEditor; - TableColumnEditor:用
ui/table实现内联可编辑单元格表格,DataTypeCell用Combobox提供类型建议,拖拽排序用 HTML5 DnD 或轻量拖拽库; - View/Procedure/FunctionEditor:封装
@/react/components/monaco/的 Monaco 组件; - PreviewPane:只读 Monaco 展示
generateDiffDDL()生成的 DDL(复用算法层)。
7.6 模态框映射
| Vue Modal | React 组件 | UI 原语 |
|---|---|---|
| ActionConfirmModal | ActionConfirmDialog | AlertDialog |
| TableNameModal | TableNameDialog | Dialog |
| SchemaNameModal | SchemaNameDialog | Dialog |
| EditColumnForeignKeyModal | EditColumnForeignKeySheet | Sheet(宽) |
| ViewNameModal | ViewNameDialog | Dialog |
| FunctionNameModal | FunctionNameDialog | Dialog |
| ProcedureNameModal | ProcedureNameDialog | Dialog |
其中仅EditColumnForeignKeyModal值得用宽Sheet——它包含带表/列选择器的多字段表单;其余均为单字段对话框(名称输入 + 确认/取消)。
7.7 纯 TS 层复用清单
以下模块不加修改直接由 React 组件导入,保留约 1,200 行经测试的逻辑,确保 Vue 与 React 实现的 DDL 生成行为完全一致:
algorithm/diff-merge.ts——元数据比较与调和algorithm/rebuild.ts——从编辑操作重建元数据algorithm/apply.ts——将变更应用到内存元数据types.ts——EditTarget、TabContext、RolloutObject、EditStatusspec.ts——引擎功能支持谓词utils/columnDefaultValue.ts——默认值占位符逻辑utils/metadata.ts——元数据转换辅助common.ts——generateDiffDDL()RPC 调用
7.8 公共 API 与桥接
React SchemaEditorLite 暴露与 Vue 版相同的接口:
- Props:
project、readonly、selectedRolloutObjects、targets、loading、hidePreview; - 回调:
onSelectedRolloutObjectsChange、onIsEditingChange; - 命令式句柄(
useImperativeHandle/forwardRef):applyMetadataEdit()、refreshPreview()、isDirty。
对于未来需要嵌入 React 版的 Vue 父组件,可做一个薄 Vue 包装器用createRoot挂载 React 组件;但初始迁移不需要——React 版只服务 React 父组件,Vue 父组件继续用 Vue 版(对应设计目标 2:零回归;以及非目标:不迁移全部 Vue 调用方)。
八、分阶段迁移计划:五阶段渐进交付
设计文档将迁移拆为 5 个阶段,每阶段都有可验证的入口/出口标准,保证"部分完成也可用":
| 阶段 | 规模 | 内容 | 出口标准 |
|---|---|---|---|
| Phase 1 基础 | ~2,000 行 | React Context Provider(替换 provideSchemaEditorContext + Emittery)、useTabs/useEditStatus/useSelection/useScrollStatus、react-resizable-panels 外壳;确认 types/spec/utils/algorithm 可被 React 导入 | 空编辑器可渲染可拖拽分栏,context 可供子组件消费 |
| Phase 2 树 | ~1,500 行 | react-arborist + 自定义节点渲染器、右键菜单(建/改/删)、节点复选框、搜索过滤 | 树可导航数据库元数据,右键菜单触发桩函数 |
| Phase 3 核心编辑器 | ~2,500 行 | Tab 容器与类型路由、TableEditor + 列编辑器(6 种单元格)、DatabaseEditor | 表列可编辑、可新建表 |
| Phase 4 扩展编辑器 | ~1,500 行 | IndexesEditor、PartitionsEditor、View/Procedure/FunctionEditor(Monaco)、PreviewPane(DDL diff) | 全部编辑器面板类型可用 |
| Phase 5 模态与打磨 | ~1,500 行 | 7 个模态对话框、编辑状态标记(created/updated/dropped 视觉标识)、滚动位置保持、applyMetadataEdit+generateDiffDDL集成测试 | 与 Vue 实现完整功能对等 |
配套实施计划(plan.md)进一步把 5 个阶段拆解为T1–T28 共 28 个任务,例如:T1 安装react-resizable-panels与react-arborist依赖(pnpm --dir frontend add react-resizable-panels react-arborist);T2 创建 context 类型与 Provider;T5 移植 628 行的useSelection(处理表/列/视图/过程/函数 5 类资源的 checked/indeterminate 状态);T8 用薄适配器把DiffMerge接入 React context;T16 创建最复杂的列编辑器与 6 个单元格组件;T24 用宽Sheet实现外键编辑表单;T27 为 5 种语言(en-US、zh-CN、ja-JP、es-ES、vi-VN)补充schema-editor命名空间 i18n key;T28 跑完整校验(fix、check、type-check、test)并确认git diff frontend/src/components/SchemaEditorLite/无改动。
九、仓库中的落地形态:从设计到实现
从当前仓库源码结构看,该迁移方案已经落地,React 版 SchemaEditorLite 位于frontend/src/modules/schema-editor/(而非设计文档最初设想的frontend/src/react/components/SchemaEditorLite/,实际落地时采用了模块化目录,这是实现细节上的演进)。落地代码与设计文档高度吻合:
- Context 层:
context.tsx实现SchemaEditorProvider与useSchemaEditorContext(),后者在 context 为空时抛错"useSchemaEditorContext must be used within a SchemaEditorProvider"; - 外壳:
SchemaEditorLite.tsx使用forwardRef+useImperativeHandle暴露命令式句柄,并渲染react-resizable-panels的PanelGroup orientation="horizontal",左面板defaultSize="25%" minSize="15%" maxSize="40%",与设计中 NSplit 的0.15/0.4/0.25参数一一对应; - 树导航:
Aside/AsideTree.tsx导入react-arborist的Tree与NodeRendererProps,tree-builder.ts将EditTarget[]构建为 react-arborist 兼容的树数据; - 状态 hook:
useTabs.ts、useEditStatus.ts、useScrollStatus.ts、useSelection.ts各自成文件;useSelection.ts接受提升的selectedRolloutObjects与onSelectedRolloutObjectsChange回调(即设计中的 Emittery 事件替换),并复用core/keyForResource.ts生成资源键; - 算法接线:
useAlgorithm.ts用cloneDeep深拷贝元数据、通过{ markEditStatusByKey, markEditStatus }薄适配器构造DiffMerge,并以setTimeout(0)替代 VuenextTick做延迟执行——与设计中"thin adapter"的描述完全一致; - 核心层:
core/algorithm/diff-merge.ts、core/spec.ts(如engineSupportsEditIndexes/engineSupportsEditTablePartitions仅支持 MYSQL/TIDB)、core/types.ts(EditTarget包含database、metadata、baselineMetadata三元组,TabType为 database/table/view/procedure/function 联合类型)作为纯 TS 层被 React 组件直接复用。
测试方面,仓库中已有DatabaseEditor.test.tsx、EditColumnForeignKeySheetLayout.test.ts、inline-input.test.tsx以及 e2e 测试frontend/tests/e2e/schema-editor/schema-editor.page.ts,印证了设计文档"每阶段产出可测试组件"的交付理念。Vue 调用方(如frontend/src/routes/project/plan-detail/components/SchemaEditorSheet.tsx)作为 React 组件嵌入到 Plan 详情流程中,体现了"React 版服务 React 父组件"的共存策略。
十、总结:一套可复用的框架增量迁移方法论
Bytebase 的 Schema Editor React 迁移定义文档展示了大体量交互组件进行框架迁移时的完整决策链路:先量化盘点现状(文件数、行数、依赖、耦合点)→ 划定非目标边界防蔓延 → 用开放问题显式记录待决方案及其默认值 → 按风险给出 L 级规模评估 → 用 headless 库与 Context 模式完成 Vue 特有机制的等价替换 → 以"纯 TS 层零改动复用"保住行为一致性 → 用五阶段渐进交付保证每一步都可测试、可回退。对于任何面临 Vue→React(或其他框架间)迁移的团队,这份定义文档与其在frontend/src/modules/schema-editor/的落地实现,都是一份可对照的工程范本。
延伸阅读
- 迁移手册(React Migration Playbook)——本次迁移遵循的仓库级规范
- 迁移设计文档——替换映射、行业基线、设计目标
- 迁移实施计划——T1–T28 任务拆解与验证命令
- React 版落地实现——SchemaEditorLite、Context、Aside、Panels、Modals、core 等实际源码
【免费下载链接】bytebaseDatabase governance built for humans and agents — controlling changes and access across every major database.项目地址: https://gitcode.com/GitHub_Trending/by/bytebase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考