为何Lexical的$create*Node、$is*Node函数要使用$前缀
Lexical 中
$create*Node/$is*Node函数使用$前缀的设计原因 在Lexical源码中,每个节点类都会配套导出$create*Node与$is*Node函数,以TextNode的实现为例:
export function $createTextNode(text?: string = ''): TextNode { return new TextNode(text); } export function $isTextNode(node: ?LexicalNode): boolean %checks { return node instanceof TextNode; }
这套命名与实现模式是官方文档明确推荐的使用规范。按照官方说明,$前缀原本用于标识“依托词法作用域实现EditorState操作”的函数:
我们选择依托词法作用域实现EditorState操作,$前缀就是这类函数的标识。
从表面实现看,$create*Node、$is*Node只是普通函数,似乎可以在任意上下文调用,并不依赖Lexical的特定词法作用域,采用这种命名设计的核心原因有三点:
- 优先保证全量API的命名一致性:Lexical里绝大多数带$前缀的方法,比如
$getSelection、$getRoot、$insertNodes,都必须在editor.update()、editorState.read()这类绑定了活跃Editor上下文的作用域中执行,脱离对应上下文调用会直接抛出错误。节点创建、类型判断本身就是编辑器状态操作链路里的高频核心逻辑,统一归入$前缀的命名体系后,开发者一眼就能识别出这是Lexical的状态操作类API,不会把它当成普通工具函数随便丢在异步回调、全局作用域里调用,从命名层面就降低了误用概率。 - 给后续版本迭代留兼容缓冲:当前版本的
$create*Node、$is*Node确实是不依赖上下文的普通逻辑,但如果后续版本需要给这类逻辑增加上下文校验——比如创建节点时检查对应节点类型有没有在当前编辑器注册、判断节点类型时区分跨编辑器实例的节点对象,不需要修改函数名就可以平滑上线,不会产生破坏性变更,已有业务代码不需要调整就能正常运行。 - 简化工程化校验的实现逻辑:Lexical官方提供了配套的ESLint规则,会自动检查所有$开头的函数是否放在合法的Editor调用上下文里。统一用$前缀做标识后,不管是框架内置的方法,还是业务层自定义的节点操作函数,只要遵循命名规范就可以自动被Lint规则覆盖,不需要单独维护一份需要校验的函数白名单,规则的通用性和扩展性会好很多。
内容的提问来源于stack exchange,提问作者Michal Kurz
相关产品推荐
相关产品推荐

