Skip to content

Frontend Introduction

worable edited this page Oct 12, 2026 · 1 revision

前端包介绍

前端包是 StackPanel 主题和插件共享的前端能力系统。它允许主题和插件携带编译后的 React 模板组件,由平台渲染。

导致静默失败的三条约束

前端包的失败大多是静默的——页面不报错,只显示「未找到插件管理页面」之类。以下三点是所有坑的根源:

  1. 必须 export default frontend。 运行时的注册表从入口模块的 default 导出解析前端包(frontend-registry.ts 的 packageOf 取 mod.default ?? mod)。只写 export const frontend 而没有 default,该插件的全部页面与路由都会变成 not-found,且不报错。构建期的元数据探测会额外接受 frontend 命名导出,但运行时只认 default。
  2. 交互式管理后台页面必须放在 src/admin.tsx,不要在 src/index.tsx 里写 ui.adminPages。 服务端入口 index.tsx 打包出的 ui.adminPages 不会被任何渲染方读取。管理后台页面是客户端组件,由 src/admin.tsx 编译成 dist/admin.js 后注册给客户端渲染。详见管理后台扩展。
  3. frontend/manifest.json 是编译产物,不要手改。 每次 pnpm build:frontend 都会根据源码重新生成它(含 revision、files 等)。手写的字段会被覆盖。要改声明就改 src/index.tsx 里的 ui / pages 等,再重新编译。

概念

一个前端包是一组编译后的 JS 组件加一份清单(manifest.json)。清单声明以下能力:

声明 说明
pages 用户可访问的页面路由
layouts 可复用的页面布局包装器
finders 类型化数据源
adminRoutes 插件的管理后台子页面
adminActions 插件的快捷操作组件
actions 表单式提交操作,平台统一处理鉴权和审计
accountRoutes 用户账户页面
accountWidgets 用户账户页面的 Widget
settingsSchema 自动生成 admin 设置表单

三级覆盖

页面渲染优先级:主题 > 插件 > 内置。

请求 /blog/hello-world
  → 主题 frontend 声明了 /blog/:slug?  → 使用主题模板
  → 否则,插件 frontend 声明了 /blog/:slug?  → 使用插件模板
  → 否则,使用内置模板

两个入口

一个插件的前端包有两个源码入口,对应两种渲染模式:

入口 编译产物 渲染位置 提供的能力
frontend/src/index.tsx dist/index.js 服务端(SSR) pages、layouts、finders、settingsSchema、ui.adminRoutes/ui.accountRoutes/ui.actions 等声明,以及服务端渲染组件 pageComponents、ui.accountPages、ui.adminWidgets、ui.adminActionComponents、ui.accountWidgetComponents、主题 overrides
frontend/src/admin.tsx dist/admin.js 客户端('use client') 交互式管理后台页面 adminPages

两个入口的分工:

  • index.tsx 里的 ui.adminRoutes 只声明路由元数据(path、component 名、permission、data 绑定);真正的组件在 admin.tsx 的 adminPages 里,两者的 component 名必须对上。
  • 只有存在 src/admin.tsx 时才会产出 dist/admin.js 并注册到客户端渲染表。没有交互需求(纯静态展示)时,可以不给 admin.tsx,但该插件就不能有管理后台页面。
  • 两个入口都可以导入 @stackpanel/ui、lucide-react、zod,这些依赖由平台外置提供。

目录结构

前端包位于主题或插件包的 frontend/ 目录:

frontend/
├── manifest.json     # 前端清单(编译产物,勿手改)
├── src/
│   ├── index.tsx     # 服务端入口(pages / finders / 路由声明)
│   └── admin.tsx     # 客户端管理后台入口(可选,交互式 admin 页)
└── dist/
    ├── index.js      # 编译后的组件(必须)
    └── admin.js      # 客户端管理后台组件(可选,来自 src/admin.tsx)

文件约束

规则 限制
manifest 路径 frontend/manifest.json
dist 路径 frontend/dist/
允许的文件 manifest.json + dist/*.js + dist/*.map
禁止的文件 .ts/.tsx/.jsx 等源码
单文件最大 1 MB
入口文件最大 512 KB

编译

前端包源码使用 TypeScript + React 编写,通过 scripts/build-frontend.mjs 编译。esbuild 以 src/index.tsx(必选)和 src/admin.tsx(可选)为入口分别打包,产物为 dist/index.js / dist/admin.js(各带 .map),而不是每个组件一个模块。

pnpm build:frontend    # 编译所有主题和插件的前端包

可携带前端包的包类型

包类型 可携带前端包 前端包能力
主题 支持 pages、layouts、finders、settingsSchema、overrides(主题专有)
插件 支持 pages、layouts、finders、settingsSchema、adminRoutes、adminActions、accountRoutes、accountWidgets、actions

Clone this wiki locally