核心概念

核心概念概览

5分钟理解 ktr 的整体架构、设计理念和数据流向

本页快速介绍 @karinjs/template-react 的核心设计——约定优于配置的截图模板框架。

5分钟理解整体架构

ktr 是一个基于 React 的 SSR 截图模板框架,核心特点:

  • 约定式路由<板块>/<模板>/index.tsx 自动注册为路由
  • 类型安全:通过模块增强实现逐路由精确类型推导
  • 开发面板 + 沙盒隔离:可视化调试界面与组件渲染环境分离
  • SSR 渲染:生产环境生成独立 HTML 供截图引擎使用
// 路由补全、data 类型推导 —— 无需手动导入组件
await ('hello/card', {
  : 'Karin Template React',
  : [{ : '渲染方式', : 'SSR HTML' }]
})

约定优于配置

框架通过文件系统约定自动发现模板、mock 数据和路由,无需手写注册表:

ktr/template/
├── hello/
│   └── card/
│       ├── index.tsx       ← 自动注册为路由 hello/card
│       ├── mock.ts         ← TS mock(类型安全)
│       └── data/
│           ├── default.json  ← JSON mock(面板可编辑)
│           └── captured.json ← 真实渲染自动捕获
└── style.css               ← 全局样式入口

启动开发服务器或执行构建时,框架扫描文件系统并生成三个注册表文件到 .ktr/ 目录:

  1. template-registry.ts —— 路由 → 组件的映射
  2. mock-registry.ts —— mock 数据的统一导出
  3. registry-types.d.ts —— TypeScript 类型增强

这些文件由框架自动管理,开发者无需关心。

开发态 vs 生产态

框架设计了两种运行模式,共享同一套核心逻辑但适配不同场景:

开发态(Development)

┌─────────────┐
│  开发面板    │ ← React UI,提供模板选择、数据编辑
│ /__ktr/panel │
└──────┬──────┘
       │ postMessage

┌─────────────┐
│ 沙盒 iframe  │ ← 加载 virtual:ktr-sandbox 虚拟模块
│  React 渲染  │ ← Vite HMR,代码改动即时更新
└─────────────┘

特点:

  • Vite 开发服务器提供热模块替换(HMR)
  • 面板与沙盒通过 postMessage 通信
  • Mock API 提供数据读写接口
  • SSE 推送数据变更,实时同步

生产态(Production)

// Karin 插件代码
const  = (import.meta.)

// SSR 渲染生成独立 HTML,内联 CSS 和主题变量
const { , ,  } = await ('hello/card', , {
  : { : 'dark', : 'oklch(0.62 0.19 254)' }
})

if (!) {
  throw new (`渲染失败:${}`)
}

// 交给 Puppeteer 截图
await ()

特点:

  • React 19 renderToReadableStream 生成 HTML
  • 内联 CSS,无外部依赖
  • 主题变量直接写入 <body> 样式
  • 输出文件可独立运行

数据流向图

开发态数据流

用户操作(选择模板 + 数据)

┌────────────────┐
│   开发面板      │ ← 从 /__ktr/api 获取模板列表和 mock 数据
│    (React)     │ ← 监听 SSE 推送,自动刷新
└───────┬────────┘
        │ postMessage({ type: 'ktr:data', payload: { path, data, ctx } })

┌────────────────┐
│  沙盒 iframe    │ ← 动态 import 模板组件
│ (React 渲染)   │ ← root.render(<Component data={data} ctx={ctx} />)
│                │ ← 测量尺寸并上报
└───────┬────────┘
        │ postMessage({ type: 'ktr:rendered', size: { width, height } })

┌────────────────┐
│   预览画布      │ ← 根据尺寸调整 iframe
│  (缩放/平移)    │ ← 支持缩放、拖拽、截图
└────────────────┘

生产态数据流

Karin 插件调用 renderImage()

┌─────────────────────┐
│ createTemplateRenderer │ ← 定位包根,加载配置
│                         │ ← 加载注册表(.ktr/ 或打包产物)
└──────────┬─────────────┘

┌─────────────────────┐
│  createRenderer      │ ← 执行 beforeRender 钩子
│                      │ ← renderToReadableStream
│                      │ ← 执行 afterRender 钩子(加工模板片段)
│                      │ ← 包装 HTML 外壳,内联 CSS
└──────────┬──────────┘

┌─────────────────────┐
│  输出 HTML 文件      │ ← dist/template/html/hello_card.html
│  (独立、可截图)      │
└──────────┬──────────┘

     Puppeteer 截图

Mock 数据的三种来源

ktr 提供三种数据源,各有适用场景:

数据源位置类型安全面板可编辑适合场景
TS mockmock.ts固定示例,插件代码可复用
JSON mockdata/*.json多组对照数据,快速调样式
捕获数据data/captured.json真实渲染自动记录
// TS mock:类型安全,编译期校验
import type {  } from './index'

export const  = {
  : 'Karin Template React',
  : [{ : '渲染方式', : 'SSR HTML' }]
} satisfies 

真实渲染后,框架自动将 { data, ctx } 写入 captured.json,开发面板通过 SSE 推送实时同步,帮助快速复现线上问题。

关键设计理念

1. 约定式架构

文件系统即路由,无需手写注册表:

  • ktr/template/hello/card/index.tsx → 路由 hello/card
  • _ 开头的目录不扫描(如 _shared/
  • components/ 目录不参与路由(模板内部组件)

2. 渐进增强

TypeScript 类型随约定文件自动生成:

// .ktr/registry-types.d.ts(框架生成)
declare module '@karinjs/template-react/registry-types' {
  interface ProjectRegistry {
    'hello/card': typeof import('../ktr/template/hello/card/index').default
  }
}

无需手动导入,renderImage 自动获得路由补全和 data 类型推导。

3. 双态统一

开发态(Vite HMR)和生产态(SSR HTML)共享:

  • 同一套模板组件
  • 同一套主题系统
  • 同一套注册表加载逻辑

差异仅在运行环境,核心代码完全复用。

4. 沙盒隔离

开发面板与模板渲染分离,避免样式污染和状态干扰:

  • 面板用 React 构建,预构建为静态资源由开发服务器托管
  • 沙盒用 iframe 隔离,独立 React 上下文
  • 通过 postMessage 通信,协议类型安全

下一步

On this page