API 参考

渲染器 API

createTemplateRenderer、createRenderer、注册表加载函数与渲染上下文类型的完整参考

插件 Node 侧胶水层用的 API,全部从主入口 @karinjs/template-react 导入。绝大多数 npm 插件只用 createTemplateRenderer(约定事项全自动);createRenderer 是底层能力,需要完全自定义来源时才用。ktr build 生成的 standalone 运行包也会导出同名的 createTemplateRendererrenderTemplate,使用方式见独立构建

createTemplateRenderer

declare const : (: string, ?: TemplateRendererOptions) => 

interface TemplateRendererOptions {
  ?: <RendererOptions> // 透传给 createRenderer 的覆盖项,在约定默认值之上合并
  ?: string // 生产打包产物目录(相对包根或绝对路径),默认按 main/exports 入口与目录扫描自动发现
}

type  = < extends keyof  & string>(
  : ,
  : <[]>,
  ?: 
) => <RenderResult>
  • callerUrl:调用方模块的 import.meta.url,用来向上定位插件包根(最多 10 层),必须原样传。
  • 惰性初始化:首次渲染时才解析配置、加载注册表、创建渲染器。

约定行为(什么都不配时自动做的):读 karin.template.ts;加载约定注册表(渲染器跑在下游 bundle 里时直接用产物,否则 .ktr 源文件优先、缺失回退产物);CSS 开发态用 dev 缓存、生产态默认按 karin 惯例发现 lib/style.css(可用 renderer.cssPath 覆盖);outputDir 默认 dist/template/html;真实渲染数据捕获到 ktr/template/<路由>/data/captured.json

src/utils/render.ts
const  = (import.meta., {
  : { : .(, .) }
})

// 路由补全和 data 类型由注册表模块增强提供
const { , ,  } = await ('hello/card', {
  : '你好',
  : [{ : '状态', : 'ok' }]
})

更多使用场景

自定义输出目录

import {  } from '@karinjs/template-react'
import  from 'node:path'

const  = (import.meta., {
  : {
    : .(.(), 'output/screenshots')
  }
})

await ('user/profile', { : '张三', : '...' })
// HTML 输出到 output/screenshots/user_profile.html

自定义主题变量

import {  } from '@karinjs/template-react'

const  = (import.meta.)

// 深色模式渲染
await (
  'hello/card',
  { : '夜间模式' },
  {
    : { : 'dark' }
  }
)

// 完整自定义主题
await (
  'hello/card',
  { : '品牌定制' },
  {
    : {
      : 'light',
      : '#FF6B6B',
      : '#FFFFFF',
      : '#F8F9FA',
      : '#212529',
      : '#DEE2E6'
    }
  }
)

// 传入 CSS 变量
await (
  'hello/card',
  { : '圆角定制' },
  {
    : {
      : { '--radius': '16px', '--spacing': '2rem' }
    }
  }
)

高清截图(2x)

import {  } from '@karinjs/template-react'

const  = (import.meta.)

await (
  'report/chart',
  { : [120, 230, 180] },
  {
    : 2 // 2 倍渲染,截图更清晰
  }
)

带时间戳的文件名

import {  } from '@karinjs/template-react'

const  = (import.meta., {
  : {
    : 'timestamp' // 每次渲染生成新文件
  }
})

// 并发渲染同一模板时不会相互覆盖
await .([('hello/card', { : 'A' }), ('hello/card', { : 'B' })])
// 输出 hello_card_1723456789012.html 和 hello_card_1723456789123.html

自定义文件名规则

import {  } from '@karinjs/template-react'

const  = (import.meta., {
  : {
    : () => {
      // 自定义规则:用横线分隔,加上日期前缀
      const  = new ().().('T')[0]
      return `${}-${.('/', '-')}`
    }
  }
})

await ('hello/card', { : '...' })
// 输出 2026-08-14-hello-card.html

关闭数据捕获

import {  } from '@karinjs/template-react'

const  = (import.meta., {
  : {
    :  // 生产环境关闭捕获
  }
})

注入额外样式

import {  } from '@karinjs/template-react'
import  from 'node:path'

const  = (import.meta., {
  : {
    : [.(.(), 'ktr/public/fonts.css'), .(.(), 'ktr/public/custom.css')]
  }
})
// fonts.css 和 custom.css 会内联到生成的 HTML <style> 中

注册渲染插件

import {  } from '@karinjs/template-react'
import type { RenderPlugin } from '@karinjs/template-react'

const : RenderPlugin = {
  : 'log-plugin',
  : () => {
    .(`[渲染] ${.}`)
  },
  : () => {
    .(`[完成] ${.}, HTML 长度: ${..}`)
  }
}

const  = (import.meta., {
  : {
    : []
  }
})

错误处理

import {  } from '@karinjs/template-react'

const  = (import.meta.)

const  = await ('hello/card', { : 'Test' })

if (!.) {
  .(`渲染失败: ${.}`)
  // 可能的错误:
  // - Template is not registered: hello/card
  // - Template data validation failed: hello/card
  // - <React 渲染或写文件的原始异常消息>
} else {
  .(`渲染成功,HTML 路径: ${.}`)
}

createRenderer

declare const : < extends <keyof , <any>>>(
  : ,
  : RendererOptions
) => < extends keyof  & string>(: , : <[]>, ?: ) => <RenderResult>

RendererOptions

Prop

Type

htmlFileName'fixed' 每模板固定一个文件覆盖写(hello/cardhello_card.html);'timestamp' 输出带时间戳的文件名(并发渲染同模板时可选);函数形式收路由、返回不含扩展名的文件主名。

渲染行为:路由未注册或 validate 未通过时返回 success: false(原因在 error),不抛异常。成功后写出完整 HTML(内联 CSS、#container 边界、按 ctx.theme 注入主题变量)并按规则写 captured.json

loadTemplateRegistry / loadMockRegistry

declare const : (?: LoadRegistryOptions) => <>
declare const : < extends <string, unknown> = <string, unknown>>(?: LoadRegistryOptions) => <>

按约定加载 ktr sync 生成的注册表,插件源码不需要 import .ktr。取新规则:渲染器自身跑在下游 bundle 里时(生产)直接用打包产物、忽略 .ktr 源码;否则 .ktr 源文件优先(开发态),缺失时回退产物(按 bundledDirmain/exports 入口目录 → 根目录扫描发现)。也可用 preferSource: false 强制产物优先。

返回值:loadTemplateRegistry 返回「路由 → 模板定义」映射(模块增强生效时逐路由精确,否则退化为 AnyRegistry);loadMockRegistry 返回各 mock.ts 具名导出 + mockDataFiles 清单(路由 → data/*.json 文件名)。

渲染上下文与主题类型

RenderContext / RenderContextInput

interface RenderContext {
  /** 当前渲染比例,截图模板通常保持为 1。 */
  : number
  /** 调用方显式提供的主题变量;框架不发明默认值。 */
  ?: <ThemeContext>
}

第三个参数 ctx 的类型是 RenderContextInput:所有字段可选,theme 只注入显式提供的字段,缺省时组件库自身主题生效。

ThemeContext

Prop

Type

RenderPlugin / PluginContext

SSR 渲染阶段的可插拔扩展:

interface RenderPlugin {
  : string // 插件名称
  ?: 'pre' | 'normal' | 'post' // 执行顺序,pre 先执行
  ?: (: string) => boolean // 返回 false 时跳过当前模板
  ?: (: PluginContext) => void | <void> // 生成 HTML 前执行
  ?: (: PluginContext & { : string }) => string | void | <string | void> // 加工 HTML
}

PluginContext 字段:path(模板路由)、data(模板数据)、ctx(运行时上下文)、outputDir(HTML 输出目录)。

On this page