funhub-material-starter
v0.0.3
Published
A starter for creating a funhub material package.
Readme
funhub-material-starter
一个用于开发、预览和发布 Funhub 物料包的 SDK 模板。
和之前只提供 SDK 打包能力的版本不同,这个模板现在把浏览器可访问的 playground 也内置在 sdk 项目里了,可以直接通过 pnpm run dev:preview 启动,不需要额外再维护一个独立的预览工程。
当前内置能力
- 使用
tsdown构建 ESM 产物和类型声明 - 内置一个基于 Next.js App Router 的 playground / preview 应用
- 示例物料
exampleMaterial - 支持服务端组件 + 客户端组件组合
- 内置
FunhubProvider、ThemeSync、next-intl等最小运行环境 - 提供
publish:npm自动补丁发版脚本
快速开始
pnpm install
pnpm run dev常用命令:
pnpm run dev
pnpm run build
pnpm run typecheck
pnpm run dev:preview
pnpm run build:preview
pnpm run start:preview
pnpm run publish:npm说明:
pnpm run dev:监听构建 SDK 产物pnpm run build:构建 SDK 包到dist/pnpm run dev:preview:启动内置 playground,默认访问http://localhost:3031pnpm run build:preview:构建内置 preview 应用pnpm run start:preview:以生产模式启动 preview 应用
项目结构
sdk/
├─ src/
│ ├─ index.ts SDK 导出入口
│ ├─ preview.ts preview 物料注册
│ ├─ global.css 对外公共样式
│ ├─ i18n/request.ts next-intl 请求配置
│ └─ sdk/materials/example/
│ ├─ material.ts 物料定义
│ ├─ schema.ts 物料属性 schema
│ ├─ server.tsx 服务端组件
│ └─ client.tsx 客户端组件
├─ app/
│ ├─ layout.tsx 内置 playground 根布局
│ ├─ page.tsx playground 首页
│ ├─ preview-providers.tsx Preview 环境 Provider
│ └─ preview.css playground 样式
├─ scripts/
│ └─ publish.js 自动升级补丁版本并发布到 npm
├─ tsdown.config.mts SDK 构建配置
└─ package.jsonSDK 打包入口
这个仓库里同时存在两套用途不同的代码:
src/index.ts:SDK 的正式打包入口,给外部业务项目消费app/**、src/preview.ts:仅用于内置 playground / preview,不会作为 SDK 对外入口
当前打包链路是:
pnpm run build通过tsdown.config.mts从src/index.ts开始构建- 产物输出到
dist/ package.json的exports["."]指向./dist/index.mjs
也就是说,真正会被 npm 包使用方 import 到的内容,取决于 src/index.ts 导出了什么,而不是 playground 里能不能看到什么。
例如:
export { exampleMaterial } from './sdk/materials/example/material';
export { inputMaterial } from './sdk/materials/input/material';如果某些文件只是 playground 运行时需要,比如:
app/page.tsxapp/preview-providers.tsxsrc/preview.ts
那么它们即使存在于仓库中,也不代表会成为 SDK 的公共导出。
Playground 怎么工作
内置 playground 使用 app/ 目录启动一个最小 Next.js 应用,页面会:
- 从
src/preview.ts读取当前可预览的物料列表 - 根据 URL 参数
?material=<type>切换当前物料,未传时回退到第一个物料 - 根据物料的
propsSchema生成默认 props - 通过物料的
serverComponent渲染当前选中的物料 - 注入
FunhubProvider、ThemeSync、国际化消息等运行时上下文
浏览器侧会自动渲染一个 playground sidebar,用来展示扫描到的物料列表,并支持直接点击切换预览。
自动扫描与自动注册
这个模板已经把 playground 的物料发现流程自动化了,不需要再手动维护一份 preview 注册表。
src/preview.ts 内部通过:
require.context('./sdk', true, /material\.ts$/)递归扫描src/sdk/**/material.ts- 读取每个模块的所有导出值
- 过滤出满足
type、name、category、icon、serverComponent、clientComponent、propsSchema结构的物料对象 - 按文件路径排序后生成
previewMaterials - 最终导出
getPreviewMaterials()和previewMaterialMap
这意味着只要你的物料文件放在 src/sdk/materials/<your-material>/material.ts,并且正确导出 defineMaterial(...) 的结果,它就会自动:
- 出现在 playground 左侧物料列表中
- 支持通过
/?material=<type>单独打开 - 被
previewMaterialMap收集,方便后续做统一查找或扩展
当前示例里,src/index.ts 负责 SDK 对外导出,src/preview.ts 负责 playground 内部自动发现;两者职责分离:
- 新物料想在 npm 包中给外部项目使用,需要补充到
src/index.ts - 新物料想在内置 playground 中预览,只需要放到
src/sdk/**/material.ts并导出即可
物料开发流程
- 在
src/sdk/materials/<your-material>/新建物料目录 - 在
material.ts中定义物料元信息和组件入口,并导出物料对象 - 在
schema.ts中定义面板属性 schema - 在
server.tsx/client.tsx中实现渲染逻辑 - 在
src/index.ts中补充 SDK 对外导出 - 执行
pnpm run dev:preview,让 playground 自动扫描并验证效果
最小示例:
import { defineMaterial } from '@funhub/platform/utils';
import { DemoClient } from './client';
import { demoInspectorPropsSchema } from './schema';
import { DemoServer } from './server';
export const demoMaterial = defineMaterial({
type: 'demo-material',
name: 'Demo Material',
icon: '',
category: '示例分类',
serverComponent: DemoServer,
clientComponent: DemoClient,
propsSchema: demoInspectorPropsSchema,
});只要这个文件路径命中 src/sdk/**/material.ts,playground 就会自动收录它。
示例物料说明
示例物料位于 src/sdk/materials/example/,由四部分组成:
material.ts:通过defineMaterial定义type、name、category、组件入口等信息schema.ts:通过zod和平台工具定义配置面板 schemaserver.tsx:服务端组件,适合处理 SSR、预取和数据拼装client.tsx:客户端交互组件
新增物料时,建议沿用这套结构,便于统一维护和批量导出。
对外导出
当前模板的根导出为:
import { exampleMaterial } from 'funhub-material-starter';后续新增物料后,继续在 src/index.ts 中补充导出即可。
构建与发布
本地构建
pnpm run build构建产物输出到 dist/。
发布到 npm
pnpm run publish:npm脚本会自动执行:
- 将
package.json的版本号按补丁版本递增一次 - 执行
npm publish - 发布失败时自动回滚版本号
发布前请确认:
- 已执行
npm login - 包名在 npm 上可用
pnpm run build已通过
Peer Dependencies
使用方需要自行提供这些运行时依赖:
reactreact-domnextnext-intl@tanstack/react-query@tanstack/query-core
