Skip to content

🛠️ 模块安装与运维

模块 module.json 描述模块包,真实安装状态由 system_modules 表决定。本页集中讲安装、启停、卸载、运行包以及自动发现规则。如果你想看 module.json 字段或 publish-manifest.json 写法,去 模块配置模块资源发布

🎯 本页目标

读完本章节后,应能掌握:

  • 模块从安装到运行所经历的完整流程。
  • 安装、覆盖安装、启用、停用、卸载几条命令在效果上的差异。
  • 何时该重新执行 module:build-runtime,运行包与本地构建如何协作。
  • 框架按目录约定自动发现路由、Provider、装修组件的规则。
  • 新增模块时推荐的初始目录结构。

🧭 模块安装

安装模块可以通过两种方式进行

1、通过后台 应用中心 安装模块;

2、通过命令行安装模块。

文件权限要求

模块安装、覆盖安装、卸载和删除都会写入或删除项目目录中的文件。无论从后台 应用中心 操作,还是执行 php artisan module:* 命令,都需要确保实际执行命令的系统用户具备对应目录权限。

常见需要写入或删除的目录包括:

路径用途
frontend/admin发布或覆盖模块 Admin 源码、生成 Admin 模块扩展文件
frontend/uniapp发布或覆盖模块 uni-app 源码、更新 pages.json 和模块装修入口
public/modules发布或删除模块 Admin / H5 运行包
modules/{Module}删除模块文件时需要移除模块目录

生产环境建议统一使用 Web / PHP 运行用户执行模块命令,例如:

bash
sudo -u www php artisan module:install {Module}

如果曾经使用 root 或其他用户执行过安装、构建、复制文件,后续通过后台 应用中心 操作时可能因为文件所有者不一致出现 Permission denied、目录不可写、发布资源无法覆盖或卸载后文件残留。此时需要先修正目录所有者和权限,再重新执行模块操作。

如要通过命令行可使用下面的 Artisan 命令 安装模块:

bash
# 安装模块:执行模块迁移、Seeder、资源发布,写入安装记录并启用模块
php artisan module:install {Module}

适用场景:

  • 首次安装模块。
  • 模块业务表已经存在,但前端发布资源目录不存在。
  • 模块卸载后需要重新安装,且发布目标目录已经被清理。

如果发布目标已经存在,需要显式覆盖:

bash
# 覆盖安装:允许覆盖已发布的 admin / uni-app 模块资源
php artisan module:install {Module} --force

适用场景:

  • 模块已经安装过,前端资源目录仍然存在。
  • 模块已安装,仍需要把 Resources 中的新版本前端源码重新发布到主工程。
  • 模块 Resources 有更新,需要重新发布到主工程。

--force 只影响资源发布覆盖,不会清空模块业务表,也不会删除业务数据。

安装流程会依次处理:

  1. 读取 modules/{Module}/module.json
  2. 检查 dependencies,例如 System
  3. 执行 modules/{Module}/Database/Migrations 下的模块迁移。
  4. 执行 Modules\{Module}\Database\Seeders\{Module}DatabaseSeeder
  5. Resources/publish-manifest.json 清理历史发布目录。
  6. 发布资源清单中声明的 admin、uni-app 资源。
  7. 写入或更新 system_modules 安装记录,并把 status 设为 1
  8. 刷新模块运行时缓存,包括模块注册、路由发现、MCP 工具发现等。
  9. 重新生成前端扩展配置,例如 admin 链接项,并把 uni-app 页面片段合并到 pages.json

已安装模块可以单独启用或停用:

bash
# 启用模块:保留安装记录,把 system_modules.status 写为 1
php artisan module:enable {Module}

# 停用模块:保留安装记录,把 system_modules.status 写为 0
php artisan module:disable {Module}

启用、停用模块会刷新模块运行时缓存。模块中的 Controller、Service Provider、MCP Tool、AI Tool 只有在模块启用后才会进入运行时。

查看模块路由是否生效:

bash
# 查看后台模块路由是否已注册,{slug} 来自 module.json.slug
php artisan route:list --path=adminapi/{slug}

# 查看用户端模块路由是否已注册,{slug} 来自 module.json.slug
php artisan route:list --path=api/{slug}

🧹 卸载命令

默认卸载:

bash
# 卸载模块:移除发布资源、菜单和前端扩展,并删除 system_modules 安装记录
php artisan module:uninstall {Module}

默认卸载会:

  • 删除安装器发布过的 admin、uni-app 资源。
  • 移除模块菜单和角色菜单关系。
  • 从 uni-app pages.json 中移除模块页面。
  • 删除 system_modules 中的模块安装记录。
  • 保留模块业务数据表。

如需连同模块迁移一起回滚,必须显式声明:

bash
# 删除模块数据结构:在默认卸载基础上回滚模块迁移,可能删除模块业务表
php artisan module:uninstall {Module} --drop-data

--drop-data 会回滚模块迁移,可能删除业务数据表。包含订单、支付、账户余额、审批记录等敏感业务数据的模块,生产环境应优先使用默认卸载,谨慎执行 --drop-data

命令影响对比:

命令发布资源菜单与权限安装记录 / 启用状态业务表与数据
module:install {Module}目标不存在时发布执行 Seeder / 安装器写入记录并设为 1已执行迁移不会重复创建,已有数据保留
module:install {Module} --force覆盖发布执行 Seeder / 安装器写入记录并设为 1已执行迁移不会重复创建,已有数据保留
module:enable {Module}不重新发布不重新执行 Seeder写为 1保留
module:disable {Module}不删除资源不删除菜单写为 0保留
module:uninstall {Module}删除已发布资源删除模块菜单和角色菜单关系删除记录保留业务表和数据
module:uninstall {Module} --drop-data删除已发布资源删除模块菜单和角色菜单关系删除记录回滚模块迁移,可能删除业务表和数据

System 是基础模块,不能卸载。

卸载后如需彻底删除模块文件,可以使用应用中心的“删除模块”操作,或执行:

bash
# 删除模块目录:要求模块已经卸载,实际删除 modules/{Module}
php artisan module:delete {Module}

卸载、删除模块和清理残留安装记录都会刷新模块运行时缓存。正常通过应用中心或 module:* 命令管理模块时,不需要额外执行 optimize:clear 才能让 MCP 工具列表感知模块启停。

如果生产环境使用 Octane、Swoole、长时间运行的队列 Worker,模块文件变更后仍应按部署方式重启对应常驻进程。常驻进程内存中的类加载状态不属于 Laravel 配置缓存,不能只依赖 optimize:clear

🚀 运行时与运行包关系

模块的 admin 页面在生产环境有两种加载路径:

  • 本地构建:模块 admin 源码已经在最近一次 npm run admin:build 时被一起打包进主 SPA。
  • 模块运行包:模块单独发布的 JS 入口,部署在 public/modules/{module}/admin/*,由 Admin 启动时按 admin.runtime_components 注册并按需加载。

Admin 加载页面时优先使用本地组件,本地不存在时回退到运行包。这样做的目的是:

  • 在生产服务器安装新模块时,可以在不重新打包 Admin 的情况下直接使用模块后台页面。
  • 后续重新打包 Admin 后,本地构建自然优先,不留陈旧入口。

构建运行包命令

bash
# 构建指定模块的 Admin 运行包:输出到 modules/{Module}/Resources/runtime/admin,并更新 publish-manifest.json
php artisan module:build-runtime {Module}

# 显式声明构建 Admin 运行包,效果与默认命令一致
php artisan module:build-runtime {Module} --admin

# 构建全部包含 Admin 页面源码的非 System 模块
php artisan module:build-runtime --all

# 也可以用 all 作为模块名构建全部模块运行包
php artisan module:build-runtime all

# 只构建运行包文件,不更新 publish-manifest.json
php artisan module:build-runtime {Module} --no-manifest

执行该命令前,管理端依赖需要已经安装:

bash
# 首次构建运行包前,在管理端目录安装依赖
cd frontend/admin
npm install

何时需要重新生成运行包

出现以下情况时通常需要重新执行 module:build-runtime

  • 修改了模块 Resources/admin 下的源码或路由组件。
  • 修改了 admin.runtime_components 入口映射,或新增了运行包组件。
  • 模块新增 / 调整了由主 Admin 共享的全局组件(例如 FooterBar 这类需要在 runtime-shared 中暴露的组件)。
  • 部署到生产服务器后,发现模块菜单点击进去页面空白或 404。

开发期已经在主 Admin 工程内调试通过的页面不强制重新生成运行包;运行包主要服务于“线上已部署 Admin,但新装/更新模块没有重打包”的场景。

与安装器的关系

安装器会按 publish-manifest.jsonfilesruntime/adminruntime/h5 复制到 public/modules/{module}/adminpublic/modules/{module}/h5。模块作者只要在打包阶段把运行包产物放到 Resources/runtime 下,安装时就会被发布到正确目录。

如果模块只有传统源码、没有运行包,仍然可以正常工作 —— 此时模块只能通过重新构建 Admin 才能在生产生效。

🔍 自动发现规则

模块运行以目录约定为主:

能力自动发现规则
模块启动注册器Modules\{Module}\Providers\{Module}ServiceProvider
Admin 控制器modules/{Module}/Http/Controllers/Admin
Api 控制器modules/{Module}/Http/Controllers/Api
Admin 模块装修组件frontend/admin/src/views/{Module}/component/decoration/widgets/*/index.ts
Admin 路由前缀/adminapi/{slug}
Api 路由前缀/api/{slug}

目录不存在时会自动跳过,不需要创建空目录占位。

🧭 新增模块建议

新增模块时推荐先创建结构:

text
modules/Shop
├─ module.json
├─ Providers/
│  └─ ShopServiceProvider.php
├─ Database/
│  ├─ Migrations/
│  ├─ Seeders/
│  └─ Support/
├─ Http/
│  └─ Controllers/
│     ├─ Admin/
│     └─ Api/
└─ Resources/
   ├─ admin/
   ├─ uniapp/
   └─ publish-manifest.json

模块自己的菜单、权限、默认配置应放到模块 Seeder 或安装器中,详见 模块配置 / 菜单与初始数据Resources/publish-manifest.json 写法详见 模块资源发布