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

快速搞定 Lexical 图片处理:实操笔记

快速搞定 Lexical 图片处理实操笔记【免费下载链接】lexicalLexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.项目地址: https://gitcode.com/GitHub_Trending/le/lexical运营丢来一张 4MB 的商品图你粘进编辑器文档 JSON 瞬间撑到好几 MB——这是 Lexical 图片处理绕不开的现实。Meta 的 Lexical 本体没有独立的图片包但 playground 里给了一套完整的图片节点、上传对话框、拖拽和图注参考实现大部分能直接搬走。这篇文章只解决一个问题这条链路怎么跑通上生产时该盯住哪几件事。 先跑通再说最短路径是复用 playground 的参考实现注册ImagesExtension再派发一条命令你就拿到了插图 对话框上传 拖拽移动全套。下面这段做了什么创建编辑器、注册图片扩展、插入一张示例图。import {buildEditorFromExtensions} from lexical/extension; import {ImagesExtension, INSERT_IMAGE_COMMAND} from ../plugins/ImagesExtension; const editor buildEditorFromExtensions([ RichTextExtension, ReactExtension, ImagesExtension, ]); editor.dispatchCommand(INSERT_IMAGE_COMMAND, { src: landscapeImage, altText: 山地风景, });节点定义在 packages/lexical-playground/src/nodes/ImageNode.tsx命令与对话框在 packages/lexical-playground/src/plugins/ImagesExtension/index.tsxlandscapeImage即 playground 自带的示例图。跑起来你会看到图插到光标处点一下出现选中框拖右下角把手能改宽高回车进入图注子编辑器。对话框里有 Sample / URL / File 三个入口File 模式走本地上传。⚙️ 它到底怎么工作的上面那条链路拆开看就是文件变 src、节点渲染、状态持久化三段。文件是怎么变成 src 的File 模式没有走命令系统里的 FileReader而是先在对话框里把文件读完再交给命令const loadImage (files: FileList | null) { const reader new FileReader(); reader.onload function () { if (typeof reader.result string) { setSrc(reader.result); // base64 data URL } return ; }; if (files ! null) { reader.readAsDataURL(files[0]); } };位于 packages/lexical-playground/src/plugins/ImagesExtension/index.tsx 中InsertImageUploadedDialogBody的上传逻辑。读完点 Confirm才会dispatchCommand(INSERT_IMAGE_COMMAND, {src, altText})。命令处理器里是$createImageNode$insertNodes落在根节点时会再包一层段落。整条链路图片节点为什么渲染时不卡编辑器ImageNode是DecoratorNode可插 React 组件的节点类型它的decorate()返回的是一个React.lazy加载的ImageComponent。图片本体用 React 18 的 Suspense 挡着useSuspenseImage新建一个new Image()预加载拿naturalWidth/naturalHeight结果存进模块级Map按 src 缓存加载失败 resolve 成{error: true}组件降级成BrokenImage占位图而不是留白。宽度上有maxWidth默认 500约束SVG 没有固有尺寸时按这个值兜底超过就等比缩。也就是说图片没下来之前编辑器只渲染一个空 span文档更新、选区、输入全不受影响。图片怎么被持久化exportJSON()存src、altText、width、height、maxWidth外加一个容易忽略的东西图注。每张图带一个嵌套的LexicalEditorWithDisposecaption.toJSON()也进 JSONimportJSONupdateFromJSON负责还原。导出 HTML 时exportDOM会生成figureimgfigcaption反向粘贴 HTML 靠DOMImportExtension的三条规则ImgRule处理裸imgFigureRule把figcaption灌进图注子编辑器。核心逻辑位于 packages/lexical-playground/src/nodes/ImageNode.tsx 和 packages/lexical-playground/src/plugins/ImagesExtension/index.tsx。真正用起来要面对的 4 件事边界情况坏图、无尺寸 SVG、Google Docs 复选框外部站点 HTML 或 Google Docs 粘贴过来时最容易出事。参考实现的处理onError落到BrokenImageisSVG判断后给无固有尺寸的 SVG 用maxWidth兜底并等比缩放isGoogleDocCheckboxImg过滤掉aria-roledescriptioncheckbox的列表小图标 img。不做的后果很具体一张 404 图把整行高度撑坏粘个 Docs 文档出来一堆莫名其妙的圆点图。性能红线base64 多大算超了本地上传走 dataURL 时base64 比原始字节膨胀约 1/3——4MB 图进 editorState 就是 5.4MB 字符串。Lexical 每次更新撤销/重做、协同 diff、toJSON落盘都会整体过一遍它另外模块级imageCache按 src 缓存且不清理data URL 会越攒越多。可量化的线单张 ≤500KB、整篇文档图片总量 ≤2MB超过就走先插入对象 URL → 上传 → 换回 CDN URL。不做的后果协同端每条消息几 MB移动端直接 OOM。上传后的持久化取舍base64 还是 CDN保存/恢复文档时要定 src 存什么。短期文档本地草稿、离线base64 自包含最省事产品化文档只存 URL。有个坑playground 的ImageNode没有setSrc只有setWidthAndHeight和setShowCaption上传完成后要么自己用getWritable()补一个 setter要么node.remove()再$insertNodes新节点。不做取舍的后果文档 10MB每次保存和首屏都传 10MB。键盘与 alt可访问性细节过无障碍验收时会被查的两点参考实现都接好了选中图片后回车把焦点移进图注子编辑器、Escape 退回主编辑器ImageResizer的按钮可聚焦、可 Tab 到达altText在对话框里是必填语义URL 模式和 File 模式各有一个输入框。不做的后果屏幕阅读器把每张图读成无上下文的图片键盘用户点不进图注。拿来就能用社区常问有没有Lexical 图片上传插件这个仓库没有独立图片包能力分散在下面几处按需取用方案适合场景引入方式已知限制ImagesExtensionplayground要现成的对话框拖拽图注缩放参考复制 packages/lexical-playground/src/plugins/ImagesExtension/依赖 playground 的 Dialog/Button/FileInput 与协作上下文搬走要替换 UIImageNode.tsx只要最小图片节点复制 packages/lexical-playground/src/nodes/ImageNode.tsx配套 ImageComponent 带协作和 TreeView 依赖需剥离无 setSrclexical/html 的 DOMImportExtension需要 HTML 粘贴/网页导入带图npm i lexical/htmlimg/figure/figcaption 规则要自己写可对照 playground 的 ImgRule/FigureRulelexical/tailwind统一编辑器样式npm i lexical/tailwind只做主题类名映射不含图片节点逻辑建议做内部文档产品直接拷 ImagesExtension 再替换 UI 组件最快已有节点体系的团队只留ImageNode命令自己接。真要裁剪的话仓库没有内置ImageResizer只做宽高缩放需自行结合第三方裁剪库不在本仓库内参考官方文档对应章节。✅ 上线前过一遍图片节点 exportJSON/importJSON 往返过一遍存一次、恢复后图还在、宽高和图注都对altText 有默认值或必填校验坏图占位文案可读单张 base64 ≤500KB超限图走上传后换 URL加载失败渲染 BrokenImage不留空白洞无固有尺寸的 SVG 走 maxWidth 兜底不撑破版式回车/Escape 键盘路径、缩放按钮 Tab 可达各测一次粘贴 Google Docs 等外部 HTML 的过滤规则生效图注为空时 blur 自动收起参考 DisableCaptionOnBlur空图注不进 JSON到这里你已有一条能进生产的 Lexical 图片处理链路节点、上传、渲染、持久化都齐了。细节以 packages/lexical-playground/src/plugins/ImagesExtension/ 的完整参考实现为准通读一遍即可。【免费下载链接】lexicalLexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.项目地址: https://gitcode.com/GitHub_Trending/le/lexical创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

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

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