Slate v2 API Helper 命名空间重命名:以 `*Api` 后缀消除 DOM 全局变量遮蔽
发布时间:2026/9/17 23:20:01 作者:尧图编辑部 阅读量:1,286

Slate v2 API Helper 命名空间重命名以*Api后缀消除 DOM 全局变量遮蔽【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate导读本文基于仓库中的 Slate v2 Api Helper Namespace Rename Ralplan 技术决策文档系统讲解 Slate v2 将公开的辅助值命名空间helper value namespaces从与模型类型同名的Node、Element、Text、Path、Point、Range等硬性重命名为NodeApi、ElementApi、TextApi等*Api后缀的过程。读完本文你将掌握该重命名要解决的核心问题浏览器全局变量遮蔽与类型/值命名空间歧义、最终 API 目标形态、决策过程与备选方案取舍、可复现的回归证明矩阵以及完整的实施与验证命令。一、问题背景为什么Node、Element、Text、Range导入是有害的Slate v2 是一个面向浏览器的富文本编辑器库其公开 API 此前采用「类型与值合并命名空间」的模式type Node与const Node共享同一个公开标识符Element、Text、Path、Point、Range同理。这种模式在浏览器环境中有两个实际痛点DOM 全局变量遮蔽Node、Element、Text、Range都是浏览器原生全局对象。应用代码中执行import { Node } from slate后同一模块作用域内的Node将指向 Slate 的辅助值对象导致new Node()、Node.ELEMENT_NODE等原生 DOM 用法被静默覆盖。文档中记录了来自 issue #5400 的真实复现Slate 的Node导入遮蔽了浏览器Node全局变量。类型/值歧义Node同时是类型数据模型中的节点联合类型又是值工具函数对象依赖 TypeScript 的 declaration merging 才能共存对人类开发者与 AI Agent 都是不必要的认知摩擦。文档中的压力测试Pressure test明确指出如果仅仅因为「Plate 也这么做」就重命名理由并不充分更强的理由是Slate v2 是浏览器面向的库当前的裸值导入在依赖声明合并的同时遮蔽 DOM 名称这是不必要的摩擦。二、决策结论Verdict硬重命名但保留模型类型最终决策是硬性重命名公开的辅助值命名空间从合并的类型/值名称改为*Api名称并附上四条红线不改名模型类型type Node、type Element、type Text、type Path、type Point、type Range以及 operation/ref/location 相关类型保持 Slate 数据模型词汇不变不为了绕开 DOM 全局变量而改成SlateNode之类。不添加公开兼容别名不提供export const Node NodeApi之类的别名。别名会让旧名称继续存活保留全局遮蔽隐患并造成自动补全噪音。不复活公开EditorApi值根级Editor值已被公开面契约裁掉编辑器的读写归属于editor.read((state) ...)与editor.update((tx) ...)。闭包结论ready for Ralph execution等待执行。三、最终 API 目标形态重命名后的理想导入形态文档给出的 Accepted targetimport { ElementApi, NodeApi, PathApi, PointApi, RangeApi, TextApi, type Element, type Node, type Path, type Point, type Range, type Text, } from slate; NodeApi.string(node); ElementApi.isElement(node); PathApi.next(path); RangeApi.edges(range);从当前仓库源码看packages/slate已按该目标落地packages/slate/src/interfaces/node.ts:38声明export const NodeApi、element.ts:20声明export const ElementApi、text.ts:31声明export const TextApi、path.ts:22声明export const PathApi、point.ts:17声明export const PointApi、range.ts:20声明export const RangeApi、operation.ts:19声明export const OperationApi、location.ts:20声明export const LocationApi、location-ref.ts中声明PathRefApi、PointRefApi、RangeRefApi根出口由 packages/slate/src/index.ts 经export * from ./interfaces/indexinterfaces/index.ts统一汇出。也就是说本文描述的重命名在当前仓库中已经是完成态*Api命名可从源码直接验证。完整重命名映射表文档给出的完整映射Current value → Target value → Type stays当前值目标值保留类型NodeNodeApiNodeElementElementApiElementTextTextApiTextPathPathApiPathPointPointApiPointRangeRangeApiRangeOperationOperationApiOperationLocationLocationApiLocationSpanSpanApiSpanPathRefPathRefApiPathRefPointRefPointRefApiPointRefRangeRefRangeRefApiRangeRefScrubberScrubberApiScrubber此前悬而未决名称的闭包决策Scrubber虽然它是可变全局配置辅助对象、并非模型辅助但为避免单独例外让「合并类型/值公开模式」继续存活仍统一为ScrubberApi而不是拆成顶层函数对。Location与Span只要其源码模块保持公开其辅助值就改为LocationApi与SpanApi。PathRef、PointRef、RangeRef辅助值分别改为PathRefApi、PointRefApi、RangeRefApi。硬性切断Hard cuts不再公开任何裸值导出Node、Element、Text、Path、Point、Range、Operation、Location、Span、PathRef、PointRef、RangeRef、Scrubber的值版本一律移除。不提供临时别名导出。内部源码在迁移单个文件期间可临时使用局部别名但最终公开根出口与公开文档必须使用*Api。四、决策过程原则、驱动因素与备选方案对比决策原则Decision Brief模型类型保持 Slate 词汇。运行时/辅助值导入默认不得遮蔽浏览器全局变量。不提供任何让已移除名称继续存活的公开别名。不复活编辑器状态静态命名空间EditorApi。迁移必须可 codemod 化、可被契约证明。主要驱动因素DOM 全局变量Node、Element、Text、Range是真实存在的浏览器原生名称。Agent 与人类 DX合并的类型/值名称更难推理。Plate 迁移先例Plate 生态已证明*Api后缀在富文本编辑器生态中读起来很自然。备选方案权衡表方案优点缺点结论保留Node、Element、Path等兼容旧 Slate 习惯改动最小保留 #5400 问题与类型/值歧义reject添加NodeApi别名但保留旧值迁移容易两种拼写并存、文档过期、自动补全噪音reject硬重命名辅助值为*Api保留模型类型消除冲突、对齐 Plate、保留 Slate 模型词汇公开破坏性变更大量导入需要改动choose连模型类型也改名如SlateNode/SlateElement消除类型命名空间冲突过度矫正伤害 Slate 近距离词汇与迁移reject额外公开EditorApi值表面一致违反已接受的 state/tx 架构复活静态编辑器思维reject选型代价NodeApi.string(node)比Node.string(node)略啰嗦但名称语义清晰读者一看便知是「辅助对象」而非「文档节点」或「DOM Node」。存量 Slate 代码片段需要 codemod 迁移文档给出了具体替换式s/\b(Node|Element|Text|Path|Point|Range|Operation|Location|Span|PathRef|PointRef|RangeRef|Scrubber)\./$1Api./外加导入语句改写import { Node } from slate→import { NodeApi } from slate。五、证据与影响范围Live Source Evidence文档以「实时源码证据」表格逐一核对了每个命名空间的现状与处置结论要点如下根出口原根模块通过通配符导出重新导出element、node、path、point、range、text、refs、operation、scrubber等接口模块导致合并的辅助值被整体暴露。Nodetype Node与const Node共享同一公开标识符 → 值改名NodeApi保留类型Node。Element / Text / Path / Range同样类型/值合并 → 分别改为ElementApi、TextApi、PathApi、RangeApi。Location / Span / refs / Scrubber这些模块同样把公开类型/接口名与辅助/配置值合并 → 改为LocationApi、SpanApi、PathRefApi、PointRefApi、RangeRefApi、ScrubberApi。公开面契约原契约要求根级存在Element、Node、Operation、Path、Point、Range、Scrubber、Text值执行时须翻转为*Api值并断言旧值名称缺失。Editor 值公开根已断言Editor in Slate为 false不新增EditorApi。Plate 先例Plate 的 slate 接口实现 使用NodeApi、ElementApi、PathApi——「偷命名不偷产品层」。旧版 Slate采用合并类型/值命名空间熟悉但正携带全局遮蔽问题。先前 v2 研究slate-v2-state-tx-public-api-and-extension-namespaces 决策文档 曾主张保留纯数据命名空间为Node、Path等本次修订为保留纯数据辅助但给值对象加Api后缀。六、Issue #5400 记账与证明路径文档明确该重命名对应 issue #5400Node导入命名空间冲突docs/slate-issues/gitcrawl-live-open-ledger.md 记录 #5400 为开放 issue其复现即 SlateNode导入遮蔽浏览器Node全局。在源码证明通过后将 docs/slate-issues/gitcrawl-v2-sync-ledger.md 中 #5400 的状态从not-claimed推进到planned-fix再提升为fixes-claimed。PR 行文本为Fixes #5400: Public helper value namespaces use *Api, so importing Slate helpers no longer shadows DOM globals such as Node.七、回归证明矩阵Regression Proof Matrix为保证重命名不是「换个名字但引入新问题」文档定义了六条必须证明的契约契约必须证明的内容根公开面根导出NodeApi、ElementApi、TextApi、PathApi、PointApi、RangeApi、OperationApi、LocationApi、SpanApi、ref APIs、ScrubberApi硬切断根不再暴露旧辅助值名称契约必须拒绝Node、Element、Text、Path、Point、Range、Operation、Location、Span、PathRef、PointRef、RangeRef、Scrubber作为运行时值类型兼容import type { Node, Element, Text, Path, Point, Range, Operation } from slate仍然可用运行时行为重命名后辅助 API 返回相同结果文档/示例公开文档与示例教授*Api导入不再遮蔽 DOM 全局下游冒烟至少一个应用/示例同时导入NodeApi与type NodeIssue #5400聚焦的源码/文档契约证明命名空间冲突已消除当前仓库中可交叉验证的实现证据包括interfaces/node.tsNodeApi.ancestor、NodeApi.ancestors、NodeApi.child等辅助方法及Ancestor、Descendant、TNode、NodeProps类型、interfaces/node.spec.tsx、interfaces/path.spec.tsx、interfaces/point.spec.tsx、interfaces/range.spec.tsx、interfaces/location-ref.spec.ts 等行为契约测试以及editor/子目录中的editor-api、editor-transforms、legacy-editor等模块。八、内部运行时、Hook/渲染 DX 与下游生态内部运行时目标在源码模块处而非仅根 barrel重命名实现常量。内部引用辅助值处更新为NodeApi、ElementApi等。仅内部使用的Editor静态表保留在slate/internal下直到既有的 Editor hard-cut 计划完成自身迁移。明确「不改行为」这是纯命名/API 契约变更。Hook / Render DX 目标公开示例中涉及 DOM 的代码不再需要Node as SlateNode这类别名来做辅助调用。类型导入保持显式import { NodeApi, type Node } from slate;文档应说明*Api名称是辅助命名空间裸类型名是文档模型。Plate 与 slate-yjs 迁移主干Plate已使用NodeApi/ElementApi/PathApi。本次重命名减少适配噪音避免 Plate 被迫把裸 Slate 辅助名翻译回其既有公开形态。slate-yjs / 协作不改变任何 operation 形状、path 形状、selection 形状、运行时 id、快照、commit 或回放行为。Operation辅助值变为OperationApi但Operation类型与序列化的 operation 记录保持不变协作证明只做导入/类型面验证不做行为验证。生态策略综合表要点系统机制Slate 目标结论Plate辅助值对象加Api后缀模型类型分离硬重命名 Slate 辅助值为*Apiagree旧版 Slate合并类型/值命名空间对象保留类型名重命名值partialSlate v2 先前计划保留纯数据命名空间公开、裁掉Editor值纯辅助保持公开为*Apirevise九、风险审查High-Risk Deliberate Mode由于这是跨根导入的公开包 API 重命名文档将其标记为高风险的「故意模式」deliberate mode并给出完整的爆炸半径与预案。爆炸半径packages/slate/src/interfaces/**packages/slate/test/**slate-react与slate-history中读取辅助值的导入docs/**与site/**changeset 与 PR 引用Pre-mortem 三大失败模式半迁移导致Node与NodeApi两种导入拼写并存。文档更新了但测试/示例仍通过陈旧的旧值导出编译通过。类型/值重命名误碰到序列化的 operation 或 node 形状。扩展证明计划单元级node、element、text、path、point、range、operation、location、refs、scrubber 的辅助 API 行为契约。公开面根导出契约要求*Api并拒绝旧值导出。类型级公开的纯类型导入仍能编译。集成级slate-react与slate-history包类型检查。文档/示例级docs 与 site 以*Api导入通过类型检查。迁移级changeset 中附带 codemod 或迁移说明。回滚/硬切断答案这应当是硬切断而非双导出。若某下游包无法在一个切片内迁移只允许在该包内部保留临时局部别名绝不放行公开根别名。十、维护者异议台账Steelman 对峙文档预演了四位维护者最可能的反对意见及其反制变更最可能异议回答迁移方案结论Node值 →NodeApi「为了命名偏好破坏所有 Slate 片段」冲突在浏览器代码中并非表面问题#5400 已报告Plate 已验证NodeApiv2 本就在做更大 API 裁切codemod 值导入与成员调用类型导入保持稳定keep保留type Node/type Element「如果全局变量是问题类型名也会冲突」模型类型是 Slate 词汇真正痛的是辅助值导入DOM 密集文件可局部别名类型普通用户无需类型迁移keep无公开别名导出「别名能让迁移更简单」双导出会让文档腐烂、自动补全噪音v2 不应发布正在移除的 footguncodemod changeset 迁移说明keepScrubber→ScrubberApi「Scrubber不是模型辅助也不是 DOM 冲突」问题是整个合并类型/值公开模式单独例外会让该模式以极小收益继续存活codemodScrubber.→ScrubberApi.keep十一、计分卡Scorecard文档以六个维度对方案打分满分 1.0维度分数React 19.2 运行时性能0.92无运行时/渲染行为变化Slate-close 无观点 DX0.92保留模型类型名、避免 DOM 全局辅助导入、拒绝别名Plate 与 slate-yjs 迁移主干形态0.94Plate 已用*Api协作数据形状不变回归证明测试策略0.93公开面契约、类型冒烟、行为契约、docs/site 类型检查、下游包类型检查、bun check研究证据完整性0.93实时源码、Plate、旧版 Slate、先前 v2 研究、导出清点、#5400 台账shadcn 式组合性与 hook/组件极简0.93API 显式不加包装器、选项、别名或产品策略加权总分0.928状态done等待用户审阅与后续 Ralph 执行。十二、实施阶段与验证命令文档为执行者Ralph列出了七步实施顺序先写红的公开面契约要求NodeApi、ElementApi、TextApi、PathApi、PointApi、RangeApi、OperationApi、LocationApi、SpanApi、PathRefApi、PointRefApi、RangeRefApi、ScrubberApi拒绝旧值导出。按家族重命名源码常量与内部导入。更新导入辅助值的包测试。更新文档、示例与 site 代码。新增或更新 changeset 并附迁移指引。仅在证明通过后在docs/slate-issues/gitcrawl-v2-sync-ledger.md、docs/slate-v2/ledgers/issue-coverage-matrix.md、docs/slate-v2/references/pr-description.md更新 issue #5400 状态。运行验证命令bun --filter slate test:vitest -- public-surface-contract bun --filter slate test:vitest -- interfaces-contract bun --filter slate typecheck bun --filter slate-react typecheck bun --filter slate-history typecheck bun x tsc --project site/tsconfig.json --noEmit bun lint:fix bun check这组命令覆盖了公开面契约测试证明*Api存在、旧值缺失、接口行为契约测试、slate/slate-react/slate-history三个包的独立类型检查、site 文档项目的 tsc 检查、lint 自动修复与全仓bun check与上文回归证明矩阵一一对应。十三、总结与审阅要点结论硬重命名所有公开合并类型/值辅助对象为*Api模型类型保持 Slate 词汇不变无公开别名无EditorApi。迁移方式codemod 替换\b(...)\b.为$1Api.类型导入不变。验证闭环公开面契约红→绿 行为契约 包类型检查 docs/site 类型检查 下游冒烟 issue #5400 台账更新加权得分 0.928开放问题为 none。该计划已在当前仓库落地完成读者可以直接在 packages/slate/src/interfaces 下查看NodeApi、ElementApi、TextApi等实现并通过 interfaces/index.ts 与 packages/slate/src/index.ts 追踪根出口形态作为「类型与值命名空间分离」设计的最佳实践参考。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考