@axiijs/axle

中文文档
0.6.0发布于 2026/08/22MITTypeScriptES Module零依赖近 30 天下载 1.2万

Reactive JSX runtime foundation for data-driven LeaferJS canvas editors.

原始使用文档
文档目录6 节
  1. 快速开始
  2. 与 React 不同的运行时契约
  3. 错误与诊断
  4. 文档
  5. Playground
  6. 开发

Axle

Reactive JSX runtime foundation for data-driven LeaferJS canvas editors.

Axle 把 axii 的响应式 Host 树模型移植到 Leafer 场景图上:

  • React 风格的 JSX,但组件函数只执行一次,直接产出真实的 Leafer UI 节点,没有 Virtual DOM。
  • 通过识别 data0 的响应式数据结构(atom / RxList / function) 把更新精确绑定到节点属性、文本与结构上。
  • RxList 的 splice / reorder / set patch 被映射为场景图上最小数量的节点操作。

快速开始

npm install @axiijs/axle data0 leafer-ui

leafer-editor 只用于仓库内的编辑器 playground,不是 Axle 运行时依赖; 使用编辑器能力的应用按需自行安装。 Axle 当前将 data0 peer 限定在已验证的 2.4.x:运行时依赖其 effect/patch 协议,升级 minor 版本前必须先通过 test/data0-contract.test.ts。

import { Leafer } from 'leafer-ui'
import { atom, RxList } from 'data0'
import { createRoot } from '@axiijs/axle'

function App() {
  const selected = atom<number | null>(null)
  const items = new RxList([1, 2, 3])

  return (
    <group>
      {items.map((value) => (
        <rect
          x={() => value * 30}
          width={20}
          height={20}
          fill={() => (selected() === value ? 'blue' : 'gray')}
          onTap={() => selected(value)}
        />
      ))}
      <text y={40}>selected: {selected}</text>
    </group>
  )
}

const leafer = new Leafer({ view: window })
createRoot(leafer).render(<App />)

TypeScript 配置(自动 JSX runtime):

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@axiijs/axle",
  },
}

Classic JSX(与 axii / Vite jsxFactory: 'createElement' 同构)时, 使用 createElement,不要把 classic 变换产物直接喂给 jsx(jsx 的第三参是 key):

/** @jsx createElement */
import { createElement, createRoot } from '@axiijs/axle'
{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "createElement",
    "jsxFragmentFactory": "Fragment",
  },
}

与 React 不同的运行时契约

Axle 使用 JSX 语法,但不是 React renderer:

  • 组件函数只执行一次;结构更新来自 function child 或 RxList patch,没有 re-render / keyed diff。
  • root.render() 每个 root 只能成功挂载一棵树;再次渲染前必须先 root.destroy()。
  • useEffect 在子树 render 后同步执行,不等待 paint;初次挂载时执行顺序是 useEffect → root attach → useLayoutEffect / ref。
  • 事件绑定只建立一次,不会响应式 rebind。handler 应在事件发生时读取 atom,而不是依赖组件重执行。
  • layout effect 与 ref attach 执行时保证子树已经连通 root.container;清理回调与 ref detach 的异常会被隔离,不会中断整棵树销毁。
  • 带 zIndex 的列表不能触发 reorder patch;叠放顺序由显式 zIndex 决定,列表只应做 splice。

完整契约见 doc/02-phase-1-design.md。

错误与诊断

渲染错误可通过 root 统一处理;窗口化、空间索引、DotLayer、共享 ticker 等独立模块可直接复用 root.reportError:

const root = createRoot(leafer, { listDiagnostics: import.meta.env.DEV })
root.on('error', (error) => reportToMonitoring(error))

const index = new SpatialIndex({
  cellSize: 512,
  onError: root.reportError,
})
const windowed = new RxWindowedList({
  index,
  resolve: (id) => models.get(id)!,
  viewRect,
  onError: root.reportError,
})

未注册 error listener、也未向独立模块传 onError 时,可恢复错误写入 console.error。 setListDiagnostics() 仍可设置全局开发期默认值;createRoot(..., { listDiagnostics }) 用于多 root 应用的实例级覆盖。

文档

Playground

仓库自带一个可交互的示例应用(响应式列表、选中高亮、拖拽、条件渲染、增量 reorder):

npm install
npm run playground   # 启动 vite,浏览器打开 playground

示例代码在 playground/main.tsx,直接引用 src/,改运行时代码即时生效。

另有两个进阶页面:

  • /canvas.html(playground/canvas.tsx)— 节点画布交互 POC (卡片拖拽、port 连线、视口缩放平移);
  • /stress.html(playground/stress.tsx)— 超大规模压测: 默认 1 万张图文/视频/文字卡片 + 按比例连线(URL 参数 ?n=50000 可到 5 万), 完整实施 doc/05-large-scale-performance.md 的视口虚拟化 / LOD / DotLayer 底衬 / 交互中降级 / 媒体门控,带 FPS、 帧时长 P95、场景图节点数等指标面板。

开发

npm install
npm run check        # typecheck + lint + test + build
npx vitest run --coverage

版本与发布记录

@axiijs/axle 共发布 25 个版本,首次发布于 2026/07/09;过去 12 个月发布了 25 个版本。

版本发布日期距今
0.6.0latest2026/08/222 个月前
0.5.102026/08/073 个月前
0.1.5legacy-0.12026/07/223 个月前
0.5.92026/07/223 个月前
0.5.82026/07/173 个月前
0.5.72026/07/163 个月前

关于 @axiijs/axle 的常见问题

@axiijs/axle 是什么?

Reactive JSX runtime foundation for data-driven LeaferJS canvas editors.

如何安装 @axiijs/axle?

在项目目录运行 npm install @axiijs/axle,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:data0(~2.16.0)、leafer-ui(^2.1.10)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@axiijs/axle 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@axiijs/axle 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@axiijs/axle 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.19。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@axiijs/axle 可以商用吗?

@axiijs/axle 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@axiijs/axle 的下载量有多少?

根据 npm 官方下载统计,@axiijs/axle 在 2026/10/08 – 2026/11/06 这 30 天内被下载 11,933 次,日均约 398 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@axiijs/axle 还在维护吗?

最新版本 0.6.0 发布于 2026/08/22(2 个月前);至今共发布 25 个版本,其中过去 12 个月发布了 25 个;首次发布于 2026/07/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。