BlockNote 开发者指南:从零搭建、目录架构到发布流程的完整实战手册
前端富文本UI组件AI 应用【免费下载链接】BlockNoteA React Rich Text Editor thats block-based (Notion style) and extensible. Built on top of Prosemirror and Tiptap.项目地址https://gitcode.com/gh_mirrors/bl/BlockNote点击查看免费下载本指南以 BlockNote 仓库的 CONTRIBUTING.md 为骨架系统讲解这套基于 Prosemirror 与 Tiptap 的块级富文本编辑器 monorepo 的目录结构、本地运行方式、常用开发命令、包发布Release流程与发布前置配置。读完本篇你将掌握从pnpm install启动开发环境到日常 lint/test/build 工作流再到通过vp run deploy完成一次 npm 发布的完整链路并理解 BlockNote 底层 Prosemirror schema 的组织方式。仓库目录结构一个多包 monorepo 的职责划分BlockNote 采用 pnpm workspace 管理根目录的 pnpm-workspace.yaml 声明了packages/*、examples/*/*、playground、docs、shared、tests等工作区。根 package.json 中packageManager: pnpm11.8.0固定了包管理器版本所有 npm scripts 均通过vpvite-plus 任务运行器分发执行。CONTRIBUTING.md 给出的目录结构如下BlockNote ├── packages/core - 编辑器核心包含在 vanilla JS 中运行编辑器的全部逻辑。 ├── packages/react - 编辑器的 React 封装与 UI需要额外的 UI 组件包配合。 ├── packages/ariakit - 基于 Ariakit 构建的 react 包 UI 组件。 ├── packages/mantine - 基于 Mantine 构建的 react 包 UI 组件。 ├── packages/shadcn - 基于 Shadcn 构建的 react 包 UI 组件。 ├── packages/server-util - 将 BlockNote 文档转换为静态 HTML服务端渲染的工具。 ├── packages/dev-scripts - 将示例编辑器配置转换为 BlockNote 网站组件的工具集。 ├── examples - 用于 BlockNote 网站和 playground 演示的示例编辑器配置。 ├── docs - BlockNote 网站代码。 ├── playground - 用于快速测试每个示例编辑器配置的基础页面。 └── tests - Playwright 端到端测试。从实际仓库看packages/下还包含大量扩展包code-block、diagram-block、math-block、xl-multi-column多列布局、xl-ai/xl-ai-serverAI 能力、xl-docx-exporter、xl-email-exporter、xl-odt-exporter、xl-pdf-exporter、xl-typst-compiler/xl-typst-exporterTypst 排版编译与导出等这些包与核心包在同一个 workspace 中统一构建与发布。值得关注的是packages/core中有一个对贡献者极其重要的文档packages/core/src/pm-nodes/README.md它详细解释了 BlockNote 的 Prosemirror schema 架构见下文源码纵深部分是理解编辑器内部数据模型的第一手资料。本地运行两条命令启动开发环境在项目根目录打开命令行执行# 安装所有必需的 npm 模块 pnpm install # 启动示例项目 pnpm devpnpm install依据根 package.json、pnpm-lock.yaml 与 pnpm-workspace.yaml 安装全部工作区依赖其中prebuild脚本会将根 README 复制到packages/core/README.md与packages/react/README.md供发布使用。pnpm dev实际执行的是vp run --filter blocknote/example-editor dev即启动 examples 中的示例编辑器项目并带 live reload热更新。如果需要单独开发文档站点可使用根脚本中的pnpm dev:docs对应vp run --filter docs dev。日常开发命令一览所有命令都在项目根目录通过pnpm运行由vpvite-plus任务运行器封装。CONTRIBUTING.md 给出了每日高频命令命令说明pnpm install安装所有依赖。pnpm dev启动示例编辑器并支持热更新。pnpm start构建 packages然后预览示例编辑器。pnpm test运行所有包的单测。pnpm lint对代码库执行 lint 与类型检查。推送前请运行此项。pnpm run check自动修复整个项目的 lint 与格式化问题。pnpm build构建所有包。pnpm e2e运行 Playwright 端到端测试。针对单个包运行单测进入该包目录后执行pnpm test追加-u参数可更新快照snapshot。对照根 package.json 的 scripts 可以还原这些命令背后的真实实现pnpm test→vp run --filter blocknote/* --filter docs test即对全部blocknote/*包与 docs 包执行测试pnpm e2e→bash tests/docker-run.sh -e CI1 -- --run通过 Docker 容器运行端到端测试详见 tests/docker-run.shpnpm lint→vp lint --type-aware启用类型感知检查pnpm run check→vp run check --fix自动修复 lint/格式化问题此外还有pnpm typechecktsc --noEmit -p tsconfig.json、pnpm formatvp fmt、pnpm install-playwright安装 Playwright 浏览器、pnpm e2e:updateSnaps更新端到端测试快照等辅助命令。从源码看 lint 与测试的组织方式根 vite.config.ts 中通过lint.plugins配置了typescript、react、import三类检查插件并开启typeAware/typeChecktest.projects则以数组形式声明了 monorepo 中各包与 tests 的测试项目每个包自己的vite.config.ts携带各自的test配置块。也就是说pnpm test会按这些 projects 逐个发现并运行各包的 Vitest 单测。新增依赖保持 lockfile 最小化向项目添加依赖时的两条规则将依赖写入相关的package.json文件如packages/xxx/package.json复查pnpm-lock.yaml确保只有相关包受到影响。值得注意的是pnpm-workspace.yaml 中配置了大量overrides例如统一tiptap/core/tiptap/pm到^3.31.3、固定vitest到4.1.10、统一shiki到^4.4.3等并设置了patchedDependencies如y/prosemirror2.0.0-6的补丁位于 patches/y__prosemirror2.0.0-6.patch。因此新增依赖后应运行pnpm install让 lockfile 重新收敛并人工 diff 确认没有意外引入其他包的版本变化。发布Releasing多包同步版本与自动化 npm 发布CONTRIBUTING.md 明确packages/下所有包以相同版本号同步发布lockstep release。发布前置条件必须处于main分支且工作区干净clean working treeCI 必须为绿色green所有公开包必须在 npm 上完成 NPM trusted publishing 配置见下文。发布流程运行交互式发布脚本vp run deploy从根 vite.config.ts 可以看到deploy任务实际执行node scripts/release.mjs并特意设置cache: false——因为发布脚本是交互式的且只产生副作用git 提交/打 tag/推送、npm publish若开启缓存会导致 vp 误判输入未变化而重放旧输出。脚本执行步骤与 scripts/release.mjs 源码一一对应校验前置条件检查工作树是否干净git status --porcelain、当前分支是否为main、本地 main 是否落后于origin/main交互式版本选择通过 bumpp 提供 patch / minor / major / prerelease / custom 选项版本号写入根package.json与全部packages/*/package.json脚本会先过滤掉只含node_modules/dist的陈旧目录同步 lockfile执行pnpm install --lockfile-only冒烟测试构建执行vp run -r build构建失败会自动git checkout -- .回滚版本号并中止生成 changelog通过 changelogen 顶部打开$EDITOR人工审阅循环打开 changelog 直到确认无误提交与打 taggit addpackage.json 集合 pnpm-lock.yaml CHANGELOG.md提交chore(release): v{version}并创建 annotated tagv{version}推送确认后git push --follow-tags推送 commit 与 tag。tag 推送后 CI 自动完成发布一旦 tag 推送CI 的 publish workflow 会自动构建所有包向 npm 发布13 个公开包并携带 OIDC provenance可验证来源证明使用 changelog 内容创建 GitHub Release。对照 .github/workflows/publish.yaml 的实现细节workflow 以v*.*.*/v*.*.*-*的 tag push 或workflow_dispatch触发发布时根据版本字符串推断 npm dist-tag含-的视为 prerelease 使用对应预发布标签否则为latest遍历packages/*/跳过private: true的包对每个公开包执行vp pm publish -- --access public --tag $DIST_TAG --provenance --no-git-checks遇到已发布/已存在错误会跳过而非失败最后通过 scripts/extract-changelog.mjs 从 CHANGELOG.md 提取对应版本段落作为 Release notesprerelease 版本会附带--prerelease标志。NPM trusted publishing 配置无需 NPM_TOKEN每个公开的blocknote/*包都必须在 npmjs.com 上配置可信发布者打开https://www.npmjs.com/package/blocknote/{name}/access在 Trusted Publisher 下选择 GitHub Actions设置为Owner TypeCellOSRepo BlockNoteWorkflow publish.yaml。不需要NPM_TOKEN密钥——发布使用 GitHub 的 OIDC token 完成身份认证publish.yaml 中permissions: id-token: write即为此而设。发布新包时的检查清单在 monorepo 中新增公开包时确保其package.json中private: false且repository字段指向 BlockNote 仓库在 npmjs.com 上为其配置 trusted publisher见上文下一次发布将自动把它纳入发布循环publish.yaml 遍历packages/*/时会自动发现并发布该公开包。源码纵深BlockNote 的 Prosemirror schema 架构CONTRIBUTING.md 指向的 packages/core/src/pm-nodes/README.md 是理解编辑器核心数据模型的关键文档。BlockNote API 中的块Block形如{ id: string; type: string; children: Block[]; content: InlineContent[] | undefined; props: Recordstring, any; }children描述子块各自拥有独立id也映射为Block类型多数情况下是嵌套块也可能是column/columnList内的块content是块的 Inline Content内联内容没有id属于节点内的松散内容。这个 API 结构与内部 Prosemirror schema 并不一一对应两者通过如下节点类型互相映射blockGroup容器节点可包含多个块。用作 Prosemirror 文档的根节点当块有嵌套子块时子块被包裹在一个blockGroup中blockContainer始终包含一个blockContent节点可选包含一个blockGroup用于嵌套子块是大多数块的包装节点正是它使得块内嵌块成为可能blockContent组决定块主元素的外观/行为如标题、段落、列表项等name与 BlockNote API 中的 block type 对应例如paragraph的 content 为inline*图片块等可无 content。schema 还定义了四个 Prosemirror 组groups组名含义blockContent以blockContainer节点表示的块的正文内容blockGroupChild允许出现在blockGroup内的东西实践中为blockContainer与columnListchildContainer可容纳对应 BlockNote API 中block.children的容器节点常规块是blockGroup列场景下columnList与column也属于此类bnBlock直接映射到 BlockNote API 中Block的节点存储idblockContainer、column、columnList均属此类该 README 特别注明后两个组bnBlock、childContainer并不在 schema 中被实际使用但编程时很有帮助——例如检查节点是否为bnBlock即可判断其是否对应一个 BlockNote Block参见getBlockInfoFromPos的实现。多列功能由xl-multi-column包实现columnList内容为column column至少两列与column内容为blockContainer至少一个块容器共同支撑块级并排排版。表格则是一类特殊的blockContent节点行与列存储在content字段而非children中表格的 children 不是块没有id。该 README 还给出了一个完整的示例文档 XML 结构blockGroup 内嵌 blockContainer / blockContent / 嵌套 blockGroup / columnList是调试文档树时的高价值参考。质量保障单测与端到端测试tests/目录承担 Playwright 端到端测试根 package.json 中e2e脚本通过 tests/docker-run.sh 在blocknote-e2eDocker 镜像中运行。该脚本的设计有几个值得借鉴的点镜像只安装依赖、不构建任何东西测试时通过vite.config.browser.ts将每个blocknote/*包解析到src/脚本将各packages/*/src目录 bind-mount 进容器因此修改packages/*/src源码后无需重建镜像即可生效通过镜像 label 中记录的blocknote.deps-hash内容哈希自动判断镜像是否过期并重建xl-typst-compiler通过构建产物pkg/、dist、types被消费运行 e2e 前需先用pnpm exec vp run --filter blocknote/xl-typst-compiler build构建会编译 Rust wasm需要 rustup。此外.github/workflows/fresh-install-tests.yml 中的 Fresh Install Tests 工作流会每天定时把公开包的生产依赖devDependencies 保持锁文件版本更新到各自 semver 范围内允许的最新版本并跑单测用于提前发现tiptap/*、prosemirror-*等上游发布新版本后与 BlockNote 声明范围冲突的问题——这正是用户在一个全新项目中执行npm install blocknote/react时会遇到的失败类型。小结本地开发pnpm installpnpm dev即可获得带热更新的示例编辑器文档站点用pnpm dev:docs。提交前pnpm lint类型感知与pnpm test是必跑项pnpm run check可自动修复格式问题。发布在干净的main分支执行vp run deploy走交互式发布脚本tag 推送后由 .github/workflows/publish.yaml 自动构建并向 npm 发布全部公开包含 OIDC provenance同时生成 GitHub Release。深入源码从 packages/core/src/pm-nodes/README.md 开始理解 blockGroup / blockContainer / blockContent 与四个 schema 组的映射关系是阅读编辑器内核代码的最佳起点。赞分享前端富文本UI组件AI 应用【免费下载链接】BlockNoteA React Rich Text Editor thats block-based (Notion style) and extensible. Built on top of Prosemirror and Tiptap.项目地址https://gitcode.com/gh_mirrors/bl/BlockNote点击查看免费下载相关推荐uv 开发实战指南从环境搭建、测试工作流到发布流程的贡献者手册uv 开发实战指南从环境搭建、测试工作流到发布流程的贡献者手册 本篇技术指南围绕 uv 仓库的 CONTRIBUTING.md https://link.gi包管理器开发工具CLIKindEditor自定义工具栏配置打造符合业务需求的编辑界面KindEditor自定义工具栏配置打造符合业务需求的编辑界面 KindEditor是一款功能强大的富文本编辑器通过灵活的工具栏配置你可以轻松打造符合自身前端UI组件FL Chart渲染缓存减少重复绘制提升性能的实现方法FL Chart渲染缓存减少重复绘制提升性能的实现方法 FL Chart是一个高度可定制的Flutter图表库支持折线图、柱状图、饼图、散点图和雷达图等多种上一篇三分钟掌握AKShare免费金融数据接口库让Python数据分析更简单下一篇react-native-reanimated 翻转卡片Flip Card实战基于 useSharedValue、interpolate 与 withTiming 实现双面内容切换创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考