最小 HTML 插件
2026/10/26大约 2 分钟
最小可运行 HTML 插件
从零落一个不构建、纯 HTML 的插件,跑通"安装 → 启用 → 打开"。适合轻量工具页、看板、老项目迁移。
目录
am-serve/plugin/am_simple/
├── manifest.json
├── Plugin.php
├── install.sql
├── config/
│ ├── route.php
│ ├── view.php
│ └── static.php
├── app/
│ ├── controller/AppController.php
│ └── view/app/index.html
└── public/manifest.json
{
"name": "am_simple",
"title": "简单插件",
"version": "1.0.0",
"support_version": "1.0.1",
"open_mode": "micro",
"entry": "/app/am_simple",
"manage_entry": "/app/am_simple",
"type": 1,
"is_dev": 1,
"path": "plugin/am_simple",
"view_root": "view",
"hook": "plugin\\am_simple\\Plugin"
}name 必须 am_ 前缀且与目录名一致;entry/manage_entry 指同一页面即可(本例只有前台)。
config/route.php(页面入口必须手动注册)
<?php
use plugin\am_simple\app\controller\AppController;
use Webman\Route;
Route::get('/app/am_simple', [AppController::class, 'index']);页面入口是无尾斜杠路径,注解生成不了,只能手动 Route::get;业务接口走注解(见下)。
app/controller/AppController.php
<?php
namespace plugin\am_simple\app\controller;
use support\Response;
use support\annotation\route\Get;
use support\annotation\route\RouteGroup;
#[RouteGroup('/app/am_simple')]
class AppController
{
protected array $noNeedLogin = ['index']; // 页面入口开放
public function index(): Response
{
return view('app/index');
}
#[Get('/info')] // GET /app/am_simple/info,需登录
public function info(): Response
{
return json(['code' => 200, 'message' => 'ok', 'data' => ['name' => 'am_simple']]);
}
}app/view/app/index.html
关键是挂出与 name 同名的 qiankun 生命周期:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>简单插件</title></head>
<body>
<div id="app"><h1>简单插件</h1><button id="btn">调用基座消息</button></div>
<script>
((global) => {
let handler = null
global.am_simple = { // 名称必须 === manifest.name
bootstrap: () => Promise.resolve(),
mount: (props) => {
const root = props.container || document
const bridge = props.hostBridge || props.amBridge
handler = () => bridge?.invoke('ui.message', { type: 'success', message: '来自简单插件' })
root.querySelector('#btn')?.addEventListener('click', handler)
return Promise.resolve()
},
unmount: () => {
document.querySelector('#btn')?.removeEventListener('click', handler)
handler = null
return Promise.resolve()
}
}
})(window)
</script>
</body>
</html>Plugin.php
<?php
namespace plugin\am_simple;
use app\basic\BasePlugin;
class Plugin extends BasePlugin
{
public function boot(array $plugin = []): void {}
}install.sql
至少放基座自动生成的"管理入口"顶级菜单幂等 INSERT(详见am_demo 全流程里的入口菜单)。纯前台、不需要后台菜单的极简插件可留空文件。
落地步骤
- 把目录放进
am-serve/plugin/; - 基座插件管理 → 扫描 → 安装 → 启用;
- 打开:直访
/app/am_simple,或从后台入口菜单进入。
常见坑
- 生命周期全局名与
manifest.name不一致 → qiankun 找不到、白屏。 config/route.php漏注册无尾斜杠入口 → 打开 404。- 改控制器注解/白名单后 Webman 反射缓存未清 → 需清缓存或重启生效。
