先选择功能归属
Extension 提供通用行为和预设;Node 描述源码节点;Mark 描述行内标记。三者共用声明式钩子,不会创建 ProseMirror schema 或另一份 JSON 文档。
| 需求 | 推荐入口 | 完整教程 |
|---|---|---|
| 修改已有功能默认值 | .configure() | 容器与嵌套块 |
| 保留语法,换按钮和组件 | .extend({ addNodeView() {} }) | 代码块定制 |
| 新语法和可写字段 | Node.create() + defineSource() | 自定义节点 |
| 新增 Markdown 解析规则 | addMarkdownExtensions() | Markdown 插件 |
| 多行图表或结构性预览 | addProjectionLayers() | 图表与代码块预览 |
| 临时状态、快捷键、输入规则 | Extension.create() | 状态、输入规则 |
create:声明可复用定义
import { Extension } from '@quirekit/msfe-core'
interface Options {
/** Host application name used by this extension. */
label: string
}
interface Storage {
/** Accepted source changes observed in this installation. */
changes: number
}
export const Audit = Extension.create<Options, Storage>({
name: 'audit',
addOptions() { return { label: 'editor' } },
addStorage() { return { changes: 0 } },
onUpdate() { this.storage.changes += 1 },
})
定义可在多个编辑器之间复用。options 与 storage 在各次安装中独立解析,不能把实例状态放在模块级变量中。storage 适合临时服务和计数;需要事务映射、撤销或投影依赖的状态使用 defineState()。
configure:修改配置
const ReportAudit = Audit.configure({ label: 'report' })
返回新定义,原定义保持不变。普通对象递归合并;数组整体替换,函数和非普通对象按值替换。配置容器 types 时,要显式保留仍需使用的默认类型。它不是已挂载实例的热更新方法;明暗、模式、只读使用实例对应方法。
extend:继承和覆盖钩子
const Audited = Audit.extend({
onUpdate(event) {
this.parent?.(event)
console.debug(this.options.label, event.revision)
},
})
覆盖钩子不会自动合并父级的结果。需要保留父行为时调用当前钩子的 this.parent?.(),数组结果由你显式拼接。需要 this.options、this.storage、this.editor、this.parent 的钩子使用普通方法,不能用箭头函数绑定外部 this。
extend 默认继承名称。用新定义替换预设中对应项,不能把同名原定义和派生定义一起安装。改名也不意味着可以让两个扩展随意占有同一段替换投影。
安装一个预设
import { StarterKit } from '@quirekit/msfe-starter-kit'
import { CodeBlock } from '@quirekit/msfe-code-block'
const CustomCodeBlock = CodeBlock.extend({
// Add the renderer from the code-block tutorial here.
})
const extensions = [
StarterKit.configure({ codeBlock: CustomCodeBlock, image: false }),
Audit,
]
addExtensions() 用于组合业务预设;应用只安装该预设一次。requires 声明依赖的扩展名称。满足依赖的扩展按 priority 从高到低安装,默认优先级为 100。名称冲突、缺失依赖等会在挂载前报告,不应靠调整数组顺序掩盖。
生命周期顺序与可做的事
| 阶段 | 已有内容 | 应做的事 |
|---|---|---|
| 配置与状态构建 | 安装定义、配置、状态槽 | 保持可重复、无 DOM 副作用 |
onBeforeCreate | 配置及状态,尚无编辑器 DOM | 准备不依赖挂载的逻辑 |
onCreate | 已挂载实例 | 建立宿主订阅,可返回清理函数 |
onUpdate | 已接受源码变化 | 增量观察、标记未保存 |
onTransaction | 包括选区和效果的已接受事务 | 有界读取,避免每次扫描全文 |
onSelectionUpdate | 选区确实发生变化 | 更新相关工具栏状态 |
onDestroy | 进入释放过程 | 逆序清理,允许重复释放资源的防御 |
组件自己的生命周期比编辑器短。滚动、源码显露、换模式可能导致组件卸载;异步资源 应绑定对应作用域。全部钩子签名见 扩展 API。
从早期描述符迁移
defineExtension() 和 defineNodeView() 仍是公开的底层入口,但其旧描述符配置不能与现代 .configure() 的深合并语义混用。新增功能优先采用这里的作者 API。MSFE 的 Tiptap 风格命名不意味着支持 parseHTML、renderHTML、content schema 或 ProseMirror 插件直接安装。