提交前自检清单
2026/10/26大约 4 分钟
提交前自检清单
插件从开发到启用,坑集中在命名、路由、注册、缓存、鉴权几处。发布或交付前逐项对照,能省掉大部分"装不上/白屏/404/接管不生效"的问题。
命名与清单
name匹配/^am_[a-z][a-z0-9_]*$/:am_前缀、后缀全小写、只含字母数字下划线。- 后缀至少 5 个字符(
MIN_NAME_SUFFIX_LEN = 5)。am_demo是预置历史示例,新建插件不要拿它当长度参照。 name不等于任何保留名(PluginManifestService::RESERVED_NAMES,含am_system/am_app/am_store/am_member等),且在库中全局唯一。- 目录名 ==
manifest.name== 命名空间末段(plugin\{name}\...)。三者不一致是最常见的装配失败原因。 path写plugin/{name},view_root、hook指向真实的视图目录与Plugin.php类。entry/manage_entry与实际页面路由一致;纯前台插件把manage_entry显式写成空串表示"无管理入口",不要漏字段导致误判。
入口菜单 code 前缀保留
app:entry: 是基座保留前缀,PluginRegistrar 会禁用插件自行声明此前缀的其它 code。install.sql 里的顶级入口菜单必须严格用 app:entry:{name}。
路由与页面入口
- 页面入口(
/app/{name}、/app/{name}/manage)是无尾斜杠路径,注解生成不出来,必须在config/route.php用Route::get手动注册。 - 业务接口走类级
#[RouteGroup('/app/{name}')]+ 方法级#[Get]/#[Post],前缀自动拼接,不要在方法里重复写前缀。 - 免登录白名单
$noNeedLogin只放行真正需要公开的方法(页面入口、公开数据接口);涉及写操作或用户数据的接口不要图省事放进去。
后端注册(生命周期与 Registry)
- 所有静态注册(事件、服务接管、适配器、中间件、任务、队列消费、身份 provider、通道鉴权)一律写在
Plugin.php::boot(),且每个 worker 进程都会重复执行,注册逻辑必须幂等。 - 每个注册都传
owner(用插件名),卸载时基座按forgetByOwner($owner)反向清理。漏传 owner 会让卸载后残留注册。 ServiceRegistry::bind/extend的优先级:基座默认实现视为优先级 0,插件接管须priority > 0才盖得住。provide()的 Provider 类必须实现ServiceProviderInterface且覆写KEY,否则抛ApiException。- 用到的扩展通道要先确认对应特性开关为
true(config/plugin_extend.php:event/service/task/queue/push/composer默认开,middleware默认关)。用中间件却发现没生效,先查middleware_enabled。
控制器返回与鉴权口径
- 基座统一响应体是
{code, msg, total, data, page},由全局 helpersuccess()/warning()/error()(底层ret())生成,键名是msg不是message,前端拦截器只读msg。手写json([...])时用message是错的(am_demo的info就是这么写的偏离,别照抄)。 - 会员鉴权
MemberAuth的错误体用的是msg不是message:未登录{code:401,msg:'请先登录'}、非会员{code:403,msg:'当前账号无权访问会员内容'}。前端取错误文案时按这个键对齐。 - 队列
dispatch、推送toChannel、任务等"尽力而为"的 API 在依赖不可用时返回false并记日志,不抛异常。调用方要按返回值降级,不要当必然成功。
前端
- qiankun 生命周期挂出的全局名必须
=== manifest.name,否则基座loadMicroApp找不到、直接白屏。 - UMD 单 bundle,
build.lib.name必须等于manifest.name。 - 前台入口(
front)默认无 Bridge、可能无登录态:调用能力前先hasBridge()判空做降级,别假设一定能拿到登录态。 - 前台页面只依赖
sdk/http、sdk/bridge(判空)与通用组件,禁止依赖菜单/worktab 等后台模块。 - 独立运行的默认入口是
front(由resolveEntryMode决定),不是manage。管理入口靠基座 qiankun 免登注入。 - 脚手架装配保留
pnpm-lock.yaml;构建顺序vite build→vue-tsc --noEmit→post-build.ts,产物按VITE_PLUGIN_ROOT回写到插件public/assets。
数据与安装
install.sql用__PREFIX__表前缀占位符、{{APP_NAME}}/{{APP_ID}}安装期占位符,由DatabaseService::executeInstallSql替换。- 建表、插菜单一律写成幂等(
CREATE TABLE IF NOT EXISTS、INSERT ... WHERE NOT EXISTS),升级重跑不能报"已存在"。 - 业务表名以
{name}_前缀;纳入备份的表在Plugin::backupTables()显式声明。 - 带 Composer 依赖的,在
manifest.composer.require声明,安装时基座按此装包、卸载清理(受composer_enabled控制)。
缓存与生效
- 改控制器注解、
$noNeedLogin、路由后,Webman 反射/路由有缓存(app/cache/ReflectionCache.php),需清缓存或重启 worker 才生效。别在"改了没反应"上浪费时间,先清缓存。 - 改
config/plugin_extend.php开关同样要重启。
最小验证路径
装 → 启用 → 打开管理入口(看是否免登注入成功、菜单是否落地)→ 直访前台 /app/{name}(看无登录态能否渲染)→ 触发一次用到的扩展通道(事件/存储/通知…)看日志与 forgetByOwner 清理是否对称。
各机制细节见生命周期、清单 manifest、服务接管 ServiceRegistry、控制器与路由、Vue3 脚手架。
