
Slate v2 核心包测试脚本闭环从根级自定义命令到包级独立test通道【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate导读本文以 Plate 仓库中 Slate v2 Core Package Test Script Closure 计划2026-04-09状态 completed为骨架梳理一套可复用的工程实践如何让slate、slate-history、slate-hyperscript等核心包的测试证明通道proof lane能够按包独立运行而不是只能通过仓库根级的自定义命令触发。读完本文你将掌握 monorepo 中包级test脚本的设计思路、plate-pkg脚本转发机制的底层实现以及 Yarn PnP 这类严格依赖隔离环境下共享依赖解析的经典坑位与修复方式并了解这套方案在当前仓库已演进为 pnpm bun中的落地形态。背景为什么要把测试通道下沉到包级在大型 monorepo本仓库packages/*下托管了 50 余个包中测试入口的管理长期存在两种典型痛点根级命令的单点依赖如果所有测试都必须通过根package.json里的自定义脚本运行那么任何包想要单独验证自己的行为都需要先理解根级脚本的参数组装逻辑无法做到进入某个包目录即测的直观体验包级脚本与根级依赖的割裂当某个包的test脚本依赖的运行时如mocha只安装在仓库根node_modules时直接在包目录执行npm test/yarn test会因为找不到可执行文件或解析不到依赖而失败——这正是 Yarn PnPPlugnPlay严格依赖隔离模式下的典型场景。该计划的目标非常明确让核心包的证明通道proof lane能够以包为单位独立运行并把验证收敛到四个可复现的命令上yarn workspace slate run test yarn workspace slate-history run test yarn workspace slate-hyperscript run test yarn test:mocha完成的四项关键改动按计划文档记录本次闭环共落地产出四项改动改动作用对象效果新增包级test脚本packages/slate/package.jsonslate包可独立跑通测试新增包级test脚本packages/slate-history/package.json历史栈history测试独立可跑修复包级test脚本packages/slate-hyperscript/package.json修复其脚本无法从包目录解析共享mocha依赖的问题拓宽根级测试通道根test:mocha车道从仅跑 smoke 文件扩展为完整slate-hyperscriptfixture 套件其中前三项解决的是包内可独立验证最后一项解决的是根级全量回归不遗漏二者共同构成完整的闭环独立开发时用包级通道合并回归时用根级通道。包级test脚本的现状实现plate-pkg转发机制计划落地时的实现载体在当前仓库中依然可查。以 packages/slate/package.json 为例其 scripts 区块这样声明{ scripts: { build: plate-pkg p:build, build:watch: plate-pkg p:build:watch, clean: plate-pkg p:clean, lint: plate-pkg p:lint, lint:fix: plate-pkg p:lint:fix, test: plate-pkg p:test, test:watch: plate-pkg p:test:watch, typecheck: plate-pkg p:typecheck } }包内并不直接书写bun test或mocha而是统一转发给私有工具包plate/scripts提供的plate-pkg二进制定义于 packages/plate-scripts/package.json 的bin字段。这种包内薄壳 根级实现的设计有两点收益跨平台安全run-with-pkg-dir.cjs的注释明确说明之所以用 Node 子进程转发而不是直接写cd ${INIT_CWD:-.} pnpm ...是因为${VAR:-default}这类展开是 bash 专属语法在 Windows 的cmd.exe下会失效。转发层统一用node:child_process的spawnSync规避了 shell 差异单一实现点所有包共享同一份p:test语义避免 50 多个包各自维护一份容易漂移的脚本。关键实现位于 packages/plate-scripts/run-with-pkg-dir.cjsconst PROJECT_CWD path.resolve(__dirname, .., ..); // 仓库根目录 const INIT_CWD process.cwd(); // 调用包目录 // p:test 分支 case p:test: { const bunTestArgs [ test, --preload, path.join(PROJECT_CWD, tooling/config/bunTestSetup.ts), ]; result runPnpm(bun, bunTestArgs); break; }这里有两个值得注意的工程细节INIT_CWD与PROJECT_CWD的分离前者是调用脚本的包目录后者固定为仓库根目录。测试运行时bun test的当前工作目录是包目录于是能自动收集该包src/**/*.spec.{ts,tsx}下的用例而--preload指向的全局 setup 文件则来自仓库根保证所有包共享同一套 DOM 与断言环境setup 文件承担全局基建tooling/config/bunTestSetup.ts 在测试用例执行前完成happy-dom/global-registrator的 DOM 全局注册、testing-library/jest-dom匹配器扩展、mock/spyOn的全局暴露并过滤了 Happy DOM 环境下 Vimeo iframe 401、iframe/脚本加载失败等无害资源错误——这些都属于包级独立跑测试能够成立的前提条件。仓库根 bunfig.toml 也为此提供了配套约束preload指向同一 setup 文件tsconfig指向tooling/config/tsconfig.test.json用于测试专用路径映射例如/registry/*并默认开启onlyFailures true让本地迭代只输出失败用例降低噪音。修复slate-hyperscriptYarn PnP 下的共享依赖解析问题计划文档记录了本次闭环中最具普适价值的一次修复slate-hyperscript包级test脚本原本无法直接运行必须改为从仓库根目录执行。原因在于 Yarn PnP该计划执行时仓库采用的包管理器的严格依赖隔离策略PnP 模式下每个包只能解析到自己在package.json中显式声明的依赖并不会像 node_modules 扁平化那样把根目录的依赖共享给所有子包。当时共享的mocha依赖实际只存在于仓库根slate-hyperscript的包级脚本从包目录出发无法解析到它测试因此无法启动。修复方案是在脚本层把执行起点锚定到仓库根目录让 mocha 能从真实存放依赖的位置完成解析。这一模式后来也被plate-pkg的PROJECT_CWD常量以更结构化的方式继承下来——PROJECT_CWD固定指向仓库根凡是需要访问根级node_modules/.bin或根级配置文件的操作如tsdown的 tooling/config/tsdown.config.ts、bunTestSetup.ts都统一以它为基准拼接绝对路径彻底绕开从包目录相对寻址根目录的脆弱写法。值得说明的是当前仓库已经完成从 Yarn mocha 到 pnpm bun 的工具链演进详见根 package.json 的packageManager: pnpm9.15.0与p:test脚本slate-history、slate-hyperscript的源码也已并入packages/slate单一包内。但共享依赖必须显式可见、脚本执行起点必须锚定依赖真实位置这一原则在 pnpm 的严格依赖布局下依然成立这也是plate-pkg转发机制至今保留的原因。拓宽根级test:mocha通道全量 fixture 不再漏测第四项改动是根级回归通道的完整性修复将根test:mocha车道从仅执行 smoke 文件拓宽为完整的slate-hyperscriptfixture 套件。其工程意义在于包级通道解决的是开发时可独立验证但独立通道无法保证全量回归时不遗漏。此前根级通道只包含 smoke 文件意味着slate-hyperscript的完整 fixture 用例在 CI 全量回归中处于未覆盖状态——即使某个改动破坏了 fixture 的序列化/反序列化行为只要 smoke 通过回归依然绿灯。拓宽后根级通道与包级通道的用例集合对齐任何包级行为变化都会被根级全量回归兜住。从当前仓库的测试分桶可以看到这套分层兜底思想的延续tooling/config/test-suites.mjs 将用例划分为快速fastpackages/**/*.spec.{ts,tsx}、慢速slow*.slow.{ts,tsx}与延期deferred三档并分别由test、test:slow、test:deferred等根级脚本驱动见根 package.jsontooling/scripts/test-fast.mjs 则负责参数解析与用例发现支持--bail、--test-name-pattern、--timeout等 bun 原生参数透传。验证命令与执行前提计划文档给出的四条验证命令构成了本次闭环的验收标准# 单包级slate 核心 yarn workspace slate run test # 单包级历史栈 yarn workspace slate-history run test # 单包级hyperscript fixture yarn workspace slate-hyperscript run test # 根级完整 mocha 回归通道 yarn test:mocha四条命令全部绿灯即证明包级通道彼此独立、均可从包维度验证根级通道覆盖完整不遗漏 fixture 套件。在当前仓库中对应的操作方式已演进为 pnpm 语法。以 packages/slate 为例其 71 个 spec 文件覆盖了编辑器创建create-editor.spec.ts、接口层interfaces/下的path、point、range、node等 spec、内部工具internal/下editor-extension、transforms、transforms-extension等目录以及历史栈packages/slate/src/slate-history 下的history.spec.tsx、with-history.spec.tsx。在仓库根执行# 仅跑 slate 包的用例等价于当年的包级通道 cd packages/slate pnpm test # 或在根目录以 workspace 过滤执行 pnpm --filter platejs/slate test而根级全量回归对应为pnpm test # 快速通道test-fast.mjs pnpm test:all # 快速 慢速 pnpm check # lint typecheck test:all test:slowest前提条件Node 与 pnpm 版本满足根 package.json 的engines约束Node 18.12.0pnpm 9.15.0且已按仓库文档完成依赖安装bun 作为测试运行时随 devDependencies 提供。总结一条可复制的包级测试闭环范式回顾本次闭环可以提炼出四条可复制的工程原则包级脚本用薄壳 转发实现包内只声明plate-pkg p:test具体语义集中在根级工具包避免多包脚本漂移同时天然获得跨平台安全执行起点锚定依赖真实位置无论是 Yarn PnP 下的 mocha还是 pnpm 下的 bun共享依赖与配置文件都应通过固定指向仓库根的PROJECT_CWD解析而不是从包目录脆弱的相对寻址包级通道与根级通道用例对齐根级回归通道必须包含完整 fixture 套件而非 smoke 子集否则独立验证通过的改动可能在回归中漏检分层分桶 统一预载环境快速/慢速/延期分桶控制回归成本bunTestSetup.ts统一提供 DOM 与断言基建使任何包都能开箱即测。这套范式不仅服务于 Slate v2 核心包的证明通道也构成了整个 Plate 仓库含platejs/*全部功能包测试体系的地基——从只能根级跑到按包可跑、根级兜底是大型编辑器 monorepo 测试工程化的关键一步。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考