拓冰建站拓冰建站
首页 / 资讯中心 / 正文

@milkdown/core 内核架构与版本演进深度解读:从 CHANGELOG 到源码实现

milkdown/core 内核架构与版本演进深度解读从 CHANGELOG 到源码实现【免费下载链接】milkdown Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown导读packages/core/CHANGELOG.md是 Milkdown 编辑器框架核心包milkdown/core的完整发布日志记录了从 3.0.0 到 7.22.1 的全部技术演进插件系统两次大重构、编辑器从有头组件走向 headless、命令系统从单命令走向可链式组合、安全模型持续加固以及 Crepe 编辑器与 AI 能力的引入。本文以这份 CHANGELOG 为骨架结合packages/core/src下的源码实现为你还原这套插件驱动 WYSIWYG Markdown 编辑器内核的启动流程、生命周期 API、内部插件流水线与关键演进脉络读完你既能读懂版本日志背后改了什么、为什么改也能掌握核心包的架构设计。一、milkdown/core 的定位插件驱动编辑器的内核层milkdown/core是 Milkdown 的发动机。根据 package.json 中的keywords它围绕markdown、prosemirror、remark、wysiwyg四个关键词展开用 remark 生态解析/序列化 Markdown用 ProseMirror 承担文档模型与编辑器视图向上对milkdown/ctx的插件容器、milkdown/transformer的解析转换、milkdown/prose的 ProseMirror 封装、milkdown/exception的错误体系进行聚合编排。从 CHANGELOG 每个版本末尾的Updated dependencies小节可以清晰看到它稳定的依赖面以 7.22.1 为例- milkdown/ctx7.22.1 - milkdown/exception7.22.1 - milkdown/prose7.22.1 - milkdown/transformer7.22.1这些工作区依赖在 package.json 中以workspace:*声明配合根目录的 pnpm-workspace.yaml 统一版本。值得注意的是v6 时代 core 还依赖milkdown/design-system进入 v7 后该依赖消失——这正是 v7编辑器成为一等公民的 headless 组件重构的直接体现样式系统从内核中剥离sideEffects: false意味着核心包不再承担任何样式副作用。src/index.ts只做两件事export * from ./editor与export * from ./internal-plugin即对外暴露编辑器类与内置插件整个包的对外 API 面非常收敛。二、编辑器生命周期与核心 API一个五态状态机打开 packages/core/src/editor/editor.ts 的 L21-L32可以看到编辑器被建模为一个显式的五态状态机export enum EditorStatus { Idle Idle, // 未初始化 OnCreate OnCreate, // 创建中 Created Created, // 已创建可交互 OnDestroy OnDestroy, // 销毁中 Destroyed Destroyed, // 已销毁 }Editor类围绕这一状态机提供一组链式 APICHANGELOG 中大量runtime plugin toggle7.0.0 引入、removable plugins6.5.0等能力都建立在此之上API作用关键行为源码依据Editor.make()创建编辑器实例静态工厂方法L49-L51config(configure)/removeConfig注入/移除全局配置函数配置函数在 create 时被Promise.all并行执行L186-L195use(plugins)挂载用户插件若编辑器已Created会立即#prepare热装载L198-L212remove(plugins)移除插件处于OnCreate时会延迟重试并给出警告L215-L231create()创建/重建编辑器OnCreate时幂等返回Created时先销毁再重建L235-L254destroy(clearPlugins)销毁编辑器可传true同时清空全部插件与配置L258-L281action(fn)获取 ctx 执行操作编辑器创建后调用如editor.action(ctx ctx.get(editorViewCtx))L285onStatusChange(cb)订阅状态变更新订阅替换旧订阅L180-L183enableInspector(enable)开启插件巡检telemetry与 7.2.0 引入的 inspector/telemetry 能力对应L172-L176inspect()收集插件运行期 telemetry未开启巡检时返回空数组并告警L289-L299use与remove之所以能在运行时动态生效是因为编辑器内部维护了用户插件存储#usrPluginStore与系统插件存储#sysPluginStore两张MapL37-L71插件在创建期通过ctx.produce产出独立上下文销毁期通过cleanup回调回收L99-L107、L110-L128。这也呼应了 6.5.0 的removable plugins、7.0.0 的runtime plugin toggle与 7.1.2/7.2.0 系列对system plugin store ref、circular deps in commands plugin的修复——插件存储的引用正确性一直是内核稳定性的关键点。三、内部插件流水线从配置到视图的启动链路Editor.create()执行#loadInternal()editor.ts L77-L96依次装载一组系统插件构成完整的启动流水线const internalPlugins [ schema, parser, serializer, commands, keymap, pasteRule, editorState, editorView, init(this), configPlugin, ]这条链路严格依赖milkdown/ctx的Timer定时器机制做拓扑排序——每个插件通过record声明自己即将就绪通过waitTimers等待前置插件的done再执行自身初始化。从各插件的 timer 依赖可以还原出完整依赖图config (ConfigReady) └─ init (InitReady)注入各 slice创建 unified().use(remarkParse).use(remarkStringify) 实例 └─ schema (SchemaReady)聚合 nodes/marks构建 ProseMirror Schema ├─ parser (ParserReady)ParserState.create(schema, remark) ├─ serializerMarkdown 序列化器 └─ commands (CommandsReady)CommandManager 就绪 └─ keymap / pasteRule / editorState / editorView以 config.ts 为例配置插件是所有异步依赖的起点L11-L33export const ConfigReady createTimer(ConfigReady) export function config(configure: Config): MilkdownPlugin { const plugin: MilkdownPlugin (ctx) { ctx.record(ConfigReady) return async () { await configure(ctx) // 执行用户在 editor.config() 里注册的所有配置 ctx.done(ConfigReady) // 通知下游插件可以继续 return () { ctx.clearTimer(ConfigReady) } } } }init.ts 则负责注入编辑器核心 sliceL31-L46包括editorCtx、prosePluginsCtx、remarkPluginsCtx、inputRulesCtx、nodeViewCtx、markViewCtx、remarkStringifyOptionsCtx与remarkCtx。它先以默认选项构建 unified 实例等ConfigReady后再读取用户通过remarkStringifyOptionsCtx覆盖的选项重建实例L48-L56——这正是 CHANGELOG 7.3.0 中Add support for remark plugin config的落地实现。schema.ts 展示了节点/标记规格如何汇聚成 SchemaL42-L73插件从nodesCtx、marksCtx收集各 preset 注册的规格extendPriorityL31-L36为每条parseDOM规则补上节点自身priority再new Schema({ nodes, marks })写入schemaCtx。这也解释了 7.22.0 修复preserve schema registration order in extendSchema (#2370)为何重要——规格注册顺序直接影响extendSchema的合并结果。parser.ts 的ParserState.create(schema, remark)L41把 remark AST 与 ProseMirror Schema 桥接起来其默认值是一个会抛出ctxCallOutOfScope()的哨兵函数L15-L17确保编辑器创建前调用 parser 会得到明确错误而非静默失败。四、命令系统演进从 CommandManager 到链式命令CHANGELOG 完整记录了命令系统的三次关键升级4.9.0Add command manager——首次引入集中式命令管理5.0.0Refactor the plugin system——插件系统整体重构由 factory 插件转向 composable 插件7.10.0Add command inline and chain——新增inline与chain两个命令编排原语7.13.0连续新增selected、toggle link、latex toggle、update block/range、expose builder in toolbar config等命令命令面大幅扩张。源码层面commands.ts 中的CommandManagerL41-L135是这一切的载体create通过CmdKey本质是 ctx 的SliceType注册命令get读取命令call拿到editorViewCtx执行command(view.state, view.dispatch, view)未就绪时抛出callCommandBeforeEditorView()异常L85、L95。其中chain()L102-L134实现了 CHANGELOG 7.10.0 宣称的链式能力语义与 ProseMirror 的chainCommands一致按顺序执行所有命令直到其中一个返回truechain (): CommandChain { const chains: CommandChain { run: () { const chained chainCommands(...commands) const view ctx.get(editorViewCtx) return chained(view.state, view.dispatch, view) }, inline: (command) { commands.push(command); return chains }, pipe: pipe.bind(this), // 通过 CmdKey 取已注册命令并压栈 } }createCmdKeyL138-L140默认值是一个恒返回false的空命令保证命令未注册时不破坏链的执行语义。e2e 目录下的 e2e/tests/command/chain.spec.ts 与bold.spec.ts正是对这一能力的端到端验证。五、v7 重构headless、composable 插件与 telemetryCHANGELOG 的7.0.0条目是理解整个 v7 架构的分水岭官方在 Major Changes 中列出五项核心变化编辑器成为一等公民的 headless 组件——内核不再强绑定任何 UI 实现UI 由milkdown/components、Crepe 等上层承担Factory 插件废弃由 composable plugins 取代——插件从工厂函数生成转向声明式可组合packages/utils下 18 个 composable 工具见 packages/utils/src/composable即为其产物运行时插件开关——即前文use/remove在Created状态下的热装载/热卸载通用 widget 插件——组件类插件code-block、image-block、list-item-block、table-block 等见 packages/components/src以统一规范接入更好的 Vue/React 支持与 API 文档。在此基础上7.2.0引入 Add inspector and telemetry随后的 7.1.2-next 系列完成rename inspection to telemetry、add support for editor inspector #960对应enableInspector()/inspect()两个 API7.6.2让 React/Vue 集成包可以直接接收 Crepe 编辑器make integrations accept crepe editor7.12.0支持 Crepe buildersupport crepe builder #1926, #1928标志着 Milkdown 从框架 插件走向开箱即用编辑器 可定制内核的双形态。v7 系列的演进顺序从 CHANGELOG 的 pre-release 版本号7.0.0-next.0 到 next.6中同样清晰可见每个 next 版本对应一次聚焦修复prosemirror 升级、collab 插件更名、block 插件 API 对齐等这是阅读 Milkdown 重构历史的重要线索。六、核心能力演进时间线从 v3 到 v7.22把 CHANGELOG 中的 Minor/Major Changes 按时间线梳理可以还原 core 包的能力成长史版本类型关键变更3.0.0Majorcore、preset-commonmark、theme-nord、plugin-math、plugin-tooltip、plugin-prism 首次发布4.0.0Minor支持 table、theme、slash commands 及大量优化4.3.0Minor增加 Vue 与 React 集成能力4.4.0Minor用 remark 替换 markdown-it解析管线重建4.5.2Minor可配置的键盘快捷键keymap4.9.0Minor引入命令管理器4.14.0Minor拆分出 prose 与 ctx 包架构解耦5.0.0Major插件系统重构functional plugin5.1.0Minorcomposable plugins API5.3.0Minor优化 Vue/React 渲染器6.0.0Majorv6 发布支持 collab协作编辑、i18n6.4.0Minorinline sync 插件、vscode 粘贴支持、新内部 ctx6.5.0Minor可移除插件、编辑器状态、table 输入规则、injectSlices7.0.0Majorheadless、composable 插件、运行时插件开关、inspector7.2.0Minorinspector 与 telemetry7.3.x~7.6.xMinor组件包逐步成型code-block、list-item-block、image-inline、link-tooltipCrepe 筹备prepare for crepe editor7.9.0Minortippy → floating-ui 迁移、schema validate props、URL 净化、UI 全面 Vue 化7.10.0Minor命令 inline 与 chain7.12.0MinorCrepe builder 支持7.15.0Minor支持扩展已扩展的 schema、新 keymap 管理器、代码块复制7.16.0Minor新增 drop indicator、highlight 插件7.17.0Minor新增 paste rule、代码块异步预览7.21.0MinorAI 能力整合OpenAI/Anthropic providers、流式输出、diff 渲染与 apply/reject7.22.0MinorCrepe AI 工具栏暴露、快捷键派生、--crepe-base-font-size主题变量等其中4.14.0 拆分 prose/ctx 包与7.9.0 全面 Vue 化是两次关键的分层决策前者把 ProseMirror 封装与插件上下文独立成包对应今天packages/prose、packages/ctx、packages/transformer的目录结构后者让组件层从自研 webcomponents 全面转向 Vue 渲染并为后续 React/Vue 双框架支持扫清障碍。七、安全与健壮性演进XSS、URL 净化与 ReDoSCHANGELOG 中安全类修复是一条高频主线值得单独梳理7.9.0sanitize url input与add validate props for schema——为链接 URL 增加净化、为 schema 增加 props 校验能力7.21.2链接 tooltip 空选区插入与外点关闭修复、粘贴链接报错修复import Fragment in image-input7.21.3sanitize unsafe link hrefs and emoji html to prevent stored XSS (#2410)——持久化 XSS 防护7.13.2修复polynomial-redos多项式级 ReDoS 漏洞7.21.1修复 Crepe 中normalizing provider baseURL的 ReDoS 风险#2366依赖安全多轮dompurify7.19.1 到 v3.3.2、7.22.1 到 v3.4.13、fast-uri修复 GHSA-v39h-62p7-jpjc、vitev6.3.4、v6.2.6 安全升级、katexv0.16.21、vitestv3.0.5等 [SECURITY] 标记升级CI 安全7.17.1 将发布流程迁移到 OIDCOpenID Connect短时令牌认证消除长期个人访问令牌的泄露风险。这些修复体现了 Milkdown 对编辑器即富文本输入面这一攻击面的重视——凡涉及用户输入链接、HTML、emoji、粘贴内容、AI provider 配置的路径都持续有安全加固。八、UI 技术栈迁移从 webcomponents 到 Vue从 tippy 到 floating-ui7.9.0是 UI 层最大的一次迁移CHANGELOG 用大量条目记录了migrate xxx to vue的系列工作code block、image inline、image block、link tooltip、list item、table、drag handle、slash menu、latex、toolbar 全部从 webcomponents 迁移到 Vue同时plugin block、plugin slash、plugin tooltip从 tippy 迁移到 floating-ui4 个 PR含 offset 配置支持。这一迁移带来一个对用户可见的破坏性变更CHANGELOG 明确给出迁移指引自定义样式选择器需从milkdown-xxx改为.milkdown-xxx不再使用 web components并列出当前全部类选择器清单.milkdown-code-block— 代码块.milkdown-image-block— 图片块.milkdown-image-inline— 行内图片.milkdown-block-handle— 块句柄.milkdown-slash-menu— 斜杠命令菜单.milkdown-toolbar— 编辑器工具栏.milkdown-link-preview/.milkdown-link-edit— 链接预览 / 编辑.milkdown-latex-inline-edit— LaTeX 编辑.milkdown-table-block— 表格.milkdown-list-item-block— 列表项如果你从 v6 升级到 v7.9 并维护过自定义样式这是必须对照检查的清单。后续版本在此基础上持续打磨7.18.0 tooltip 自动更新、7.22.0 工具栏项可访问名accessible name等均围绕这套 Vue 组件体系展开。九、升级实践如何把 CHANGELOG 当作迁移手册除了读历史CHANGELOG 更是升级决策的一手依据。结合文档与源码升级时建议关注以下三类信号1. 破坏性变更Major与迁移提示v7.0.0factory 插件废弃需迁移到 composable pluginsv7.9.0自定义 CSS 选择器从milkdown-xxx改为.milkdown-xxx。2. 配置项增减Minor 中的 Refactor7.21.0refactor: remove broken config options from diff and streaming plugins——Diff/Streaming 插件移除了失效配置项若你使用这两个插件需检查配置代码7.5.0Crepe 新增 widgets texts 与 icons 配置7.20.0image-block 新增maxWidth/maxHeight配置7.17.3uploader 新增额外参数与配置7.6.3tooltip/slash/block 新增root选项。3. 已知问题与回归修复关注fix:前缀条目是否命中你的使用场景如 7.19.2 修复从 Google Docs 粘贴多表格、7.22.1 修复 readonly 代码块同步更新、7.19.1 修复 inline code 与粗体/斜体混排时 Markdown 序列化错误关注perf:条目评估升级收益如 7.22.0 降低keepTableAlignPlugin与prismPlugin的逐键开销、7.21.0 对屏幕外代码块懒初始化 CodeMirror。版本节奏总结从文档归纳Major对应架构级破坏变更v5/v6/v7 三次Minor稳定引入新能力命令、插件、配置、Crepe/AIPatch以 bug 修复与依赖安全升级为主pre-release-next.x用于发布前的渐进验证。依赖同步方面每个版本末尾的Updated dependencies区块都会列出需要同步升级的milkdown/ctx、milkdown/exception、milkdown/prose、milkdown/transformer版本由于它们使用workspace:*同步发布整体升级时建议保持这些包版本一致避免跨版本混用。十、深入阅读指引生命周期与 API packages/core/src/editor/editor.tsEditorStatus枚举见 L21-L32create/destroy/action/inspect见 L235-L299内部插件流水线packages/core/src/internal-plugin 下的config.ts、init.ts、schema.ts、parser.ts、serializer.ts、commands.ts、keymap.ts、paste-rule.ts、editor-state.ts、editor-view.ts核心 slice 定义packages/core/src/internal-plugin/atoms.tseditorViewCtx、editorStateCtx、remarkCtx、nodeViewCtx等依赖与构建配置packages/core/package.json、packages/core/tsconfig.json命令链的端到端验证e2e/tests/command/chain.spec.ts、e2e/tests/command/bold.spec.ts完整版本记录packages/core/CHANGELOG.md。如果你正在二次开发 Milkdown 或规划从旧版本升级建议以本文梳理的生命周期 API → 内部插件流水线 → 命令系统 → 安全基线 → UI 迁移五条主线为框架逐条对照 CHANGELOG 中的feat/fix/refactor条目即可快速定位到源码层面的对应实现。【免费下载链接】milkdown Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门