npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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
  • 支持服务端组件 + 客户端组件组合
  • 内置 FunhubProviderThemeSyncnext-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:3031
  • pnpm 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.json

SDK 打包入口

这个仓库里同时存在两套用途不同的代码:

  • src/index.ts:SDK 的正式打包入口,给外部业务项目消费
  • app/**src/preview.ts:仅用于内置 playground / preview,不会作为 SDK 对外入口

当前打包链路是:

  • pnpm run build 通过 tsdown.config.mtssrc/index.ts 开始构建
  • 产物输出到 dist/
  • package.jsonexports["."] 指向 ./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.tsx
  • app/preview-providers.tsx
  • src/preview.ts

那么它们即使存在于仓库中,也不代表会成为 SDK 的公共导出。

Playground 怎么工作

内置 playground 使用 app/ 目录启动一个最小 Next.js 应用,页面会:

  • src/preview.ts 读取当前可预览的物料列表
  • 根据 URL 参数 ?material=<type> 切换当前物料,未传时回退到第一个物料
  • 根据物料的 propsSchema 生成默认 props
  • 通过物料的 serverComponent 渲染当前选中的物料
  • 注入 FunhubProviderThemeSync、国际化消息等运行时上下文

浏览器侧会自动渲染一个 playground sidebar,用来展示扫描到的物料列表,并支持直接点击切换预览。

自动扫描与自动注册

这个模板已经把 playground 的物料发现流程自动化了,不需要再手动维护一份 preview 注册表。

src/preview.ts 内部通过:

  • require.context('./sdk', true, /material\.ts$/) 递归扫描 src/sdk/**/material.ts
  • 读取每个模块的所有导出值
  • 过滤出满足 typenamecategoryiconserverComponentclientComponentpropsSchema 结构的物料对象
  • 按文件路径排序后生成 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 并导出即可

物料开发流程

  1. src/sdk/materials/<your-material>/ 新建物料目录
  2. material.ts 中定义物料元信息和组件入口,并导出物料对象
  3. schema.ts 中定义面板属性 schema
  4. server.tsx / client.tsx 中实现渲染逻辑
  5. src/index.ts 中补充 SDK 对外导出
  6. 执行 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 定义 typenamecategory、组件入口等信息
  • schema.ts:通过 zod 和平台工具定义配置面板 schema
  • server.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

使用方需要自行提供这些运行时依赖:

  • react
  • react-dom
  • next
  • next-intl
  • @tanstack/react-query
  • @tanstack/query-core