news 2026/9/10 3:58:51

tldraw 仓库中的 `@tldraw/tldraw` 遗留兼容包:它是什么、如何工作、为何应该改用 `tldraw`

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tldraw 仓库中的 `@tldraw/tldraw` 遗留兼容包:它是什么、如何工作、为何应该改用 `tldraw`

tldraw 仓库中的@tldraw/tldraw遗留兼容包:它是什么、如何工作、为何应该改用tldraw

【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. World's best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw

导读

在 tldraw SDK 的 monorepo 中,packages/namespaced-tldraw目录对应 npm 包@tldraw/tldraw,这是一个为历史兼容而保留的“薄壳”包:它本身不实现任何画布逻辑,而是完整地重新导出标准tldraw包的全部 API,并注册库版本信息与打包 CSS 资源。本文将基于该包在仓库中的 README、源码、构建脚本与测试,拆解它的定位、实现机制、构建流程与许可约束,并给出从旧包名迁移到tldraw的实操建议。

一、这个包为什么存在:历史包袱与迁移过渡

阅读 packages/namespaced-tldraw/README.md 可以看到,官方对该包的定位非常直白:"This package is kept around for legacy purposes. It just tracks the normaltldrawpackage. Please install that one instead."

也就是说:

  • @tldraw/tldraw是被保留的旧包名,仅用于照顾历史用户与存量代码;
  • 它本身不维护独立功能,而是始终跟踪并跟随标准tldraw的发布节奏;
  • 新项目应当直接安装tldraw,而不是@tldraw/tldraw

从仓库中的 package.json 可以印证这一点:该包的"name"@tldraw/tldraw,版本号与tldraw包完全一致(当前均为 5.4.0),其唯一运行时依赖就是"tldraw": "workspace:*"(monorepo 工作区引用,保证两者永远同步发布)。

二、包的结构:一个几乎“空”的入口

整个包的结构非常精简,核心文件只有三个:

文件作用
src/index.ts包的唯一入口:重新导出tldraw并注册版本
src/index.test.ts验证导出完整性的单元测试
scripts/copy-css-files.mjs构建期合并生成tldraw.css

其 API 报告(api-report.api.md)也证实了这一点——整个包的公开 API 只有一行:

export * from "tldraw";

这意味着@tldraw/tldraw的完整类型面(TypeScript 类型、Editor类、Tldraw组件、各类 shape 工具、Vec/VecModel等几何工具与类型)与tldraw逐字一致,不会多也不会少。

三、核心实现:re-export 与版本注册的完整机制

3.1 入口文件的完整逻辑

packages/namespaced-tldraw/src/index.ts全文仅数行,但包含了两个关键动作:

import { registerTldrawLibraryVersion } from 'tldraw' // eslint-disable-next-line tldraw/no-export-star export * from 'tldraw' registerTldrawLibraryVersion( (globalThis as any).TLDRAW_LIBRARY_NAME, (globalThis as any).TLDRAW_LIBRARY_VERSION, (globalThis as any).TLDRAW_LIBRARY_MODULES )

动作一:全量重新导出export * from 'tldraw'让使用旧包名的代码无需改动即可获得tldraw的全部命名导出。文件头部的eslint-disable-next-line tldraw/no-export-star注释说明仓库的 lint 规则本身反对export *的写法(避免命名冲突与 API 面失控),但此处的通配导出是有意为之——它正是“兼容壳”的本质。

动作二:注册库版本信息registerTldrawLibraryVersion接收三个来自globalThis的注入值(TLDRAW_LIBRARY_NAMETLDRAW_LIBRARY_VERSIONTLDRAW_LIBRARY_MODULES),这些值由构建期工具注入,用于在运行时把当前加载的 SDK 版本与模块清单登记到全局,便于调试、错误上报与版本一致性检测。

值得注意:tldraw包自身的入口 packages/tldraw/src/index.ts 也以完全相同的模式在文件末尾调用registerTldrawLibraryVersion。也就是说,@tldraw/tldrawtldraw的“自我注册”行为完全对齐,二者在运行时行为上没有可感知差异。

3.2 底层依赖关系

从 package.json 可以进一步看到这个壳的边界:

  • dependencies:仅tldraw(workspace 引用),其余一切由tldraw内部消化;
  • peerDependenciesreact: ^18.2.0 || ^19.2.1react-dom: ^18.2.0 || ^19.2.1,与tldraw包 packages/tldraw/package.json 声明的 peer 范围一致——React 18.2 及以上、React 19.2.1 及以上均可;
  • engines.node: ">=22.12.0":开发与构建环境要求 Node.js 22.12 或更高版本。

tldraw包本身则聚合了@tldraw/editor@tldraw/state@tldraw/store@tldraw/tlschema@tldraw/driver等核心工作区包以及@tiptap/*(文本编辑)、idb(IndexedDB 持久化)、lz-string(压缩)等依赖。因此当你的应用只安装tldraw时,画布引擎、状态管理、数据模型与 UI 全套能力都会随之就位。

四、构建机制:CSS 从哪来

由于壳包自身没有 UI 源码,它的样式文件需要在构建期生成。packages/namespaced-tldraw/scripts/copy-css-files.mjs实现了这一逻辑:

let combinedContent = [ join(packageDir, '..', 'editor', 'editor.css'), join(packageDir, '..', 'tldraw', 'src', 'lib', 'ui.css'), ].reduce((acc, path) => { const content = readFileSync(path, 'utf8') acc += content + '\n' return acc }, `/* THIS CSS FILE IS GENERATED! ... */`)

该脚本将两份源样式拼接为最终的tldraw.css

  1. packages/editor/editor.css——来自@tldraw/editor的核心画布样式;
  2. packages/tldraw/src/lib/ui.css——来自tldraw的 UI(工具栏、菜单、面板等)样式。

脚本注释特别说明:它直接从源文件生成 CSS,而不是依赖tldraw构建产出的tldraw.css,这是为了避免 lazyrepo 缓存跳过 prebuild 步骤时产物缺失的问题。对应的 package.json scripts 也体现了这条流水线:

"predev": "node ./scripts/copy-css-files.mjs", "dev": "chokidar '../tldraw/tldraw.css' -c 'node ./scripts/copy-css-files.mjs'", "prebuild": "node ./scripts/copy-css-files.mjs", "build": "yarn run -T tsx ../../internal/scripts/build-package.ts"

即:开发时用chokidar监听源 CSS 变化并自动重新合并;构建前通过predev/prebuild钩子强制生成。"files"字段中仅发布tldraw.css,说明这个包在 npm 上真正对外提供的就是“JS re-export + 一份合并样式”。

五、质量保障:测试如何验证“壳”的完整性

packages/namespaced-tldraw/src/index.test.ts用两个用例确保 re-export 没有失效:

import * as tldraw from './index' it('exports things from tldraw', () => { expect(tldraw).toHaveProperty('Tldraw') expect(new tldraw.Vec()).toMatchObject({ x: 0, y: 0 }) }) it('exports types from tldraw', () => { const _thing: tldraw.VecModel = { x: 0, y: 0 } })
  • 第一个用例验证值导出Tldraw组件存在(toHaveProperty),并且Vec是可实例化的类(new tldraw.Vec()得到{ x: 0, y: 0 },说明构造默认值正确);
  • 第二个用例验证类型导出VecModel这样的 TypeScript 类型也能从壳包导入并被正常使用。

这两个测试恰好覆盖了“值”与“类型”两个维度,确保export * from 'tldraw'的两类导出都健康。测试运行使用vitest,并复用根目录 vitest.config.ts 体系——该包的 vitest.config.ts 直接继承internal/config/vitest/node-preset标准 Node 预设,无额外覆盖。

六、使用建议:新项目请直接安装tldraw

结合 README 的指引与仓库实现,对使用者最直接的结论是:

# 旧写法(兼容,但不推荐用于新项目) yarn add @tldraw/tldraw # 推荐写法 yarn add tldraw

迁移时你几乎不需要改动业务代码,因为两个包的导出面完全一致(这正是export *的意义所在)。唯一需要留意的差异点是:

  • 样式导入:确认你的样式引用从@tldraw/tldraw/tldraw.css切换到tldraw/tldraw.css,二者都是构建期由同一份源 CSS 生成的合并文件;
  • peer 依赖:确保 React 版本落在^18.2.0 || ^19.2.1区间内;
  • Node 版本:仓库开发环境要求 Node >= 22.12.0(对应engines字段)。

如果你正在阅读tldraw的源码(比如 packages/tldraw/src/index.ts 中的EditorTldraw等全部导出),可以把@tldraw/tldraw当作一层透明的代理来理解:任何对它的调用最终都落在tldraw包上。

七、许可与商标:沿用 SDK 的统一约束

README 还交代了使用该包时需要注意的合规边界,这里同样适用于tldraw包:

  • 许可:作为 tldraw SDK 的一部分,本包依据 tldraw SDK 许可提供(见仓库根目录 LICENSE.md);
  • 水印要求:你可以将 tldraw SDK 用于商业或非商业项目,但前提是保留画布上的 “Made with tldraw” 水印;如需移除水印,需要购买商业许可;
  • 商标:tldraw 名称与 Logo 是 tldraw Inc. 的商标(Copyright (c) 2024-present tldraw Inc.),使用需遵守仓库根目录 TRADEMARKS.md 中的商标使用准则。

结语

@tldraw/tldraw是 tldraw 演进史留下的一个“版本钉子”:它用最克制的实现(一行通配导出 + 版本注册 + 构建期 CSS 合并)保证了旧用户的无痛升级,同时让仓库的 API 面与许可约束保持单一事实来源。理解它的存在,能帮你避免在排查依赖时被两个相似包名迷惑——记住核心结论即可:功能永远以tldraw为准,@tldraw/tldraw只是它的镜像。

【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. World's best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 3:58:39

Keploy 快速上手:3 步把真实流量变成可重放的 API 测试

Keploy 快速上手:3 步把真实流量变成可重放的 API 测试 【免费下载链接】keploy Open-source platform for creating safe, isolated production sandboxes for API, integration, and E2E testing. 项目地址: https://gitcode.com/GitHub_Trending/ke/keploy …

作者头像 李华
网站建设 2026/9/10 3:58:32

边缘计算在工业控制中的落地实践:从选型到部署的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 3:56:31

工作流导入复用实战:Dify、n8n、扣子三平台踩坑与效率指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 3:55:25

团队协作编程工具横评:7款主流方案实测与选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华