别只会预设模式Univer 插件架构一图看懂电商/金融项目选型照着抄【免费下载链接】univerThe Office Harness for AI Agents — Spreadsheets, Docs, Slides, Canvas, Relational Tables, and PDF in one runtime.项目地址: https://gitcode.com/GitHub_Trending/un/univer翻开 Univer 的文档绝大多数教程会带你走同一条最快路径引入UniverSheetsCorePreset传一个容器节点createUniver一把梭表格就渲染出来了。这条路径确实能帮你 5 分钟跑通 Demo但如果你以为预设模式就是 Univer 的全部那么在真正进入电商、金融这类对权限、性能、交付体积和定制深度都有硬要求的项目时很容易踩进demo 能跑、上线受阻的坑。原因很简单Univer 里并没有所谓的预设模式这个运行时模式预设Preset本质上是官方替你打包好的一组插件清单。理解这层关系你就拿到了选型的钥匙什么时候照抄预设什么时候该拆开插件自己组装。本文结合仓库源码把预设 vs 插件这条分界线、插件注册与命令通信机制讲透并给出电商与金融场景可直接照抄的选型对照表。预设不是一种模式是一摞插件的组合套餐先看仓库里预设的物理形态。presets/src/preset.ts 中IPreset的定义极其简单export interface IPreset { plugins: IPresetPlugin[]; locales?: IUniverConfig[locales]; }也就是说一个预设 一个插件数组 可选的本地化语言包。而createUniver所做的工作就是把预设里的插件逐一解包、去重后注册到同一个Univer实例上presets/src/preset.tsexport function createUniver(options: CreateUniverOptions) { const univer new Univer({ /* ... */ }); presets?.forEach((preset) { const { plugins } Array.isArray(preset) ? preset[0] : preset; plugins.forEach((p) { // 以 pluginName 为 key 做去重后注册者覆盖先注册者 pluginsMap.set(realPlugin.pluginName, { plugin: realPlugin, options: pluginConfig }); }); }); pluginsMap.forEach(({ plugin, options }) { univer.registerPlugin(plugin, options); }); const univerAPI FUniver.newAPI(univer); return { univer, univerAPI }; }注意两个细节其一插件以pluginName为唯一键存入 Map同名插件后进覆盖先进其二如果你在presets之外又显式注册了一个已被预设包含的同名插件createUniver会直接抛错Plugin xxx already registered by presets or other ways!防止重复注册导致状态混乱。组合套餐的典型代表是UniverSheetsCorePresetpresets/packages/preset-sheets-core/src/preset.ts它一口气打包了 12 个插件网络层、文档内核、渲染引擎、UI 外壳、公式引擎、电子表格内核、数字格式、公式 UI……每个插件还支持通过 config 传入精细配置return { plugins: [ UniverNetworkPlugin, [UniverDocsPlugin, { hasScroll: docs?.hasScroll }], UniverRenderEnginePlugin, [UniverUIPlugin, { container, toolbar, ribbonType, menu, contextMenu }], UniverDocsUIPlugin, useWorker ? [UniverRPCMainThreadPlugin, { workerURL: workerSrc }] : null, [UniverSheetsPlugin, { isRowStylePrecedeColumnStyle: sheets?.isRowStylePrecedeColumnStyle }], // ... ].filter((v) !!v) as IPreset[plugins], };更值得学习的是它的可选 Worker 分支当传入workerURL时主线程会挂上UniverRPCMainThreadPlugin公式引擎切换为不执行、只注册的notExecuteFormula: true状态计算任务全部交给配套的 preset-sheets-core/src/worker.ts 中UniverSheetsCoreWorkerPreset所定义的公式 Worker。这正是 Univer 处理大数据表格性能的关键设计界面渲染与公式计算分离线程。在官方示例里多个预设像积木一样堆叠examples/src/sheets/mount.tsconst presets [ UniverSheetsCorePreset({ container: host, ribbonType }), UniverSheetsDrawingPreset(), UniverSheetsConditionalFormattingPreset(), UniverSheetsFilterPreset(), UniverSheetsHyperLinkPreset(), UniverSheetsDataValidationPreset(), UniverSheetsFindReplacePreset(), UniverSheetsNotePreset(), UniverSheetsSortPreset(), UniverSheetsTablePreset(), UniverSheetsThreadCommentPreset(), ]; const { univer, univerAPI } createUniver({ presets });所以预设模式 vs 插件模式的真实分界线不是两种运行时而是你站在包工头还是总装车间的视角预设模式 站在包工头视角按功能域表格/筛选/批注成批进货插件模式 站在总装车间视角按pluginName逐个精确装配装什么、装多少、以什么配置装全部自己说了算。包体大小、启动耗时、依赖可控性全在这条分界线的哪一侧。插件注册与通信机制实战插件的户口本与生命周期在 packages/core/src/services/plugin/plugin.service.ts 中所有插件必须继承Plugin基类并声明一组静态元数据——pluginName全局唯一 ID、packageName版本对齐用、type绑定到 Sheet/Doc/Slide 等单元类型export abstract class Plugin extends Disposable { static pluginName: string; static packageName pkg.name; static version pkg.version; static type: UniverInstanceType UniverInstanceType.UNIVER_UNKNOWN; onStarting(): void {} onReady(): void {} onRendered(): void {} onSteady(): void {} }四个生命周期钩子对应 Univer 实例的四个阶段Starting依赖注入与装配、Ready注册渲染模块、初始化控制器、RenderedUI 已挂载、Steady一切就绪。把逻辑放进正确阶段是避免插件间互相抢跑的核心纪律。插件之间还允许显式声明依赖。DependentOn装饰器会把依赖写入构造器上的DependentOnSymbolpackages/core/src/services/plugin/plugin.service.tsDependentOn( UniverDocsPlugin, UniverFormulaEnginePlugin, UniverRenderEnginePlugin, UniverSheetsPlugin, UniverDocsUIPlugin, UniverSheetsHyperLinkPlugin, UniverSheetsUIPlugin ) export class UniverSheetsHyperLinkUIPlugin extends Plugin { /* ... */ }而PluginService._loadFromPlugins会基于依赖关系做拓扑排序DFS被依赖的插件先实例化未被注册的依赖会被自动补齐注册。这也解释了预设内部插件顺序为何是安全的——顺序由依赖图决定而非数组字面量顺序。一个真实的、完整的插件生命周期样板可以在 packages/sheets-hyper-link-ui/src/plugin.ts 里看到onStarting注入服务与控制器onReady把渲染控制器注册进IRenderManagerService并实例化交互控制器onRendered才拉起弹窗、权限等重度依赖模块。插件间的通信命令总线插件之间不直接互相调用方法而是通过ICommandService这条命令总线通信。在 packages/core/src/services/command/command.service.ts 中命令被分为三类COMMAND业务编排命令会进一步触发 MUTATIONMUTATION真正写入快照snapshot的数据变更是协同编辑冲突解决的最小单元OPERATION不落快照的 UI 态变更滚动位置、侧边栏开关等。命令 ID 采用命名空间.类型.命令名的约定例如sheet.command.set-range-values。业务代码无需关心命令由哪个插件注册只需面向 ID 编程。Facade API 把这层包装得更薄packages/core/src/facade/f-univer.tsuniverAPI.executeCommand(sheet.command.set-range-values, { value: { v: Hello, Univer! }, range: { startRow: 0, startColumn: 0, endRow: 0, endColumn: 0 } });命令执行前后分别有beforeCommandExecuted与onCommandExecuted监听点。这是插件扩展能力的核心钩子拦截、审计、埋点、权限校验都可以挂在这里而不侵入业务代码——对金融类强合规场景尤其重要。架构层面把插件、命令总线、公式引擎、渲染层之间的关系画成一页图docs/img/sheet-architecture.png 给出了官方视角的完整分层电商、金融场景的选型对照表下面这张对照表可以直接抄进你的技术方案评审文档。核心判断维度交付速度、包体与性能、定制深度、协作能力、维护成本。维度预设模式Preset 组合插件模式手动装配集成速度极高一个createUniver跑通低需理解依赖图与生命周期包体/首屏偏大需配合 Tree Shaking精确可控按需装插件功能覆盖官方按功能域打包开箱即用完全自定义可只装内核定制深度通过 preset 的 config 透传可写自定义插件、覆盖依赖协作能力preset 已含 RPC/Worker 骨架需自行组合协同相关插件维护成本升级跟随官方 preset 节奏版本对齐与依赖管理需自查电商预算有限、功能要全、上线要快电商后台表格的典型诉求是SKU 批量导入导出、条件格式标异常价、筛选/查找、下拉数据校验、多语言、移动端要能看。这类项目直接照抄预设组合是最优解——UniverSheetsCorePreset打底按需追加UniverSheetsFilterPreset、UniverSheetsDataValidationPreset、UniverSheetsFindReplacePreset、UniverSheetsConditionalFormattingPreset参照 examples/src/sheets/mount.ts 的拼装方式。一个官方示例里非常实用的技巧是移动端插件替换examples/src/mount-example.ts预设包只认pluginName所以可以建立一个桌面插件名 → 移动端插件的映射表用replacePresetPlugins在保持 preset 清单不变的前提下整体换血实现一套配置、双端渲染export function replacePresetPlugins(presets: IPreset[], replacements: Mapstring, PluginCtorPlugin): IPreset[] { return presets.map((preset) ({ ...preset, plugins: preset.plugins.map((entry) { const [plugin, config] Array.isArray(entry) ? entry : [plugin]; return [replacements.get(plugin.pluginName) ?? plugin, config]; }), })); }电商报表多为读多写少公式计算量可控可以暂时不配 Worker一旦涉及几千行公式联动把workerURL配上、切换成UniverSheetsCoreWorkerPreset的线程分离模式改造成本也只是一行配置。金融性能是底线权限与合规是红线金融场景交易台账、风控模型参数表、对账底稿的诉求完全不同数据量大、公式重计算频繁、操作必须可审计可回滚、多实例要隔离。服务端合规报表金融里很多表格能力要在 Node.js 服务端无头运行生成对账报表、批量重算公式。此时不要引入 UI 插件直接面向preset-sheets-node-corepresets/packages/preset-sheets-node-core/src/preset.ts装配纯内核插件配合 Worker 公式引擎在服务端完成计算。操作审计与回滚所有数据变更必须经过CommandType.MUTATION天然进入命令栈配合onCommandExecuted监听点把每次变更写入审计日志撤销/重做由IUndoRedoService兜底。在 presets/src/preset.ts 中可以看到开启collaboration: true时createUniver会把本地IUndoRedoService等覆盖为null——即协同模式 用远端变更集取代本地回滚栈这是金融场景做多人协作时最容易忽略的语义切换。多实例隔离银行往往需要在同一页面嵌入多个隔离的表格多账户、多币种视图。Univer 的每个实例持有独立Injector依赖注入容器packages/core/src/univer.ts 中createUniverInjector支持传入parentInjector构建注入器层级插件与服务在实例间天然隔离一个页面挂 10 个实例互不污染。官方多实例能力可参考 docs/img/multi-instances.png迁移路径预设起步插件收尾对大多数团队正确的工程策略不是二选一而是两段式演进MVP 阶段直接用官方预设快速验证业务价值把UniverSheetsCorePreset 3~4 个功能预设跑通重点确认交互模型和数据结构Workbook/Sheet/Formula符合业务规模化阶段当出现预设装不进业务的诉求自定义单元格渲染、私有权限协议、专属命令审计链、包体瘦身沿着依赖图把 preset 拆开逐个替换为自研插件并通过DependentOn声明与官方插件的关系。只要理解预设 插件集合 注册顺序拆与装都是同一套语言registerPlugin、PluginService的拓扑排序、ICommandService的命令总线。Univer 的插件化设计把能力边界划得异常清晰——数据在命令里流动UI 在渲染控制器里生长公式在独立引擎里计算协作在变更集里同步。看懂这条边界无论是电商的快还是金融的稳选型都只是在同一个架构上做加减法。【免费下载链接】univerThe Office Harness for AI Agents — Spreadsheets, Docs, Slides, Canvas, Relational Tables, and PDF in one runtime.项目地址: https://gitcode.com/GitHub_Trending/un/univer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考