Skip to content

Plugin Structure

worable edited this page Oct 20, 2026 · 2 revisions

插件项目结构

一个典型的 StackPanel 插件项目结构如下:

my-plugin/
├── src/
│   └── index.ts          # 插件入口,导出 definePlugin() 结果
├── frontend/             # 可选:前端包
│   ├── src/
│   │   ├── index.tsx     # 服务端入口(页面 / Finder / 路由声明)
│   │   └── admin.tsx     # 客户端入口(可选,交互式管理后台页面)
│   └── manifest.json     # 前端清单(编译产物,勿手改)
├── assets/               # 可选:静态资源,打包时原样收入 ZIP
├── dist/                 # 编译产物(scripts/build-plugin.mjs 输出)
│   ├── index.js          # 后端入口(ZIP 必须包含)
│   ├── index.js.map
│   └── index.d.ts        # 类型声明(打包时需排除)
├── manifest.json         # 插件清单(打包时自动生成或手写)
├── signature.json        # 可选:Ed25519 签名
├── tsconfig.json         # 类型检查(noEmit)
├── tsconfig.build.json   # 出声明(declaration)
└── package.json

关键文件说明

src/index.ts

插件后端入口。导出一个 PluginDefinition,通常通过 definePlugin() 包装以获得类型检查:

import { definePlugin } from '@stackpanel/sdk';

export default definePlugin({
  manifest: { id: 'my-plugin', name: 'My Plugin', version: '1.0.0' },
  routes: [/* ... */],
  onActivate(ctx) {
    /* ... */
  },
});

详见 生命周期 和 路由定义。

manifest.json

插件的元数据清单,声明 ID、名称、版本、依赖、权限等。详见 插件清单。

如果使用 pnpm plugin:pack 打包,manifest 会从 package.json 自动生成。也可以手写。

frontend/

可选的前端包目录。如果插件需要提供用户页面、管理后台页面或 Dashboard Widget,在此声明。详见前端包开发。

两个源码入口:

  • src/index.tsx — 服务端入口:公开页面(pages)、Finder、账户页,以及路由声明(ui.adminRoutes / ui.accountRoutes)。
  • src/admin.tsx — 客户端入口('use client'):交互式管理后台页面(adminPages)。见管理后台页面入口。

frontend/manifest.json 由 pnpm build:frontend 生成,不要手改。

dist/

scripts/build-plugin.mjs 的编译产物。上传 ZIP 时只包含 dist/index.js 和 dist/index.js.map,不包含 .d.ts 文件(上传校验会把 .d.ts 当作源码 .ts 拒绝)。

ZIP 包结构

最终上传的 ZIP 内部结构:

my-plugin-1.0.0.zip
├── manifest.json
├── dist/
│   ├── index.js
│   └── index.js.map
├── frontend/              # 可选
│   ├── manifest.json
│   └── dist/
│       ├── index.js       # 服务端入口产物
│       └── admin.js       # 客户端入口产物(有 src/admin.tsx 时)
├── assets/                # 可选:静态资源
├── signature.json         # 可选
└── (不允许 .ts/.tsx/.jsx/.mts/.cts 源码,含 .d.ts.map)

Clone this wiki locally