使用 InvenTree Plugin Creator 快速搭建插件:安装、开发、构建与发布的完整实战指南
【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree
InvenTree 的开源插件体系十分强大且灵活,但其复杂程度对新手开发者并不友好。本文以官方提供的inventree-plugin-creator命令行脚手架工具为主线,完整讲解从安装工具、交互式创建插件、以可编辑模式安装到 InvenTree 实例、激活并调试前后端代码,到最终编译前端资源、构建 Python 发行包并发布到 PyPI 的全流程。读完本文,你将掌握一套可直接复用的 InvenTree 插件开发工作流,并理解其背后的源码级实现原理(mixin 注册机制、开发模式静态文件重定向、Vite manifest 哈希查找等)。
Plugin Creator 是什么:为什么需要脚手架工具
InvenTree 服务端通过可扩展的插件架构,允许第三方功能直接嵌入安装实例,从而在与核心代码解耦的前提下实现复杂行为(参见 插件架构总览)。插件可以来自多种渠道:
- 通过
pip安装的第三方包; - 放置于外部 plugins 目录的本地插件;
- InvenTree 源码内置的 built-in 插件。
然而,插件的灵活与强大也意味着上手门槛较高:一个合格插件通常需要同时编排 mixin 声明、包元数据、前后端静态资源、版本管理与 CI 配置。Plugin Creator 正是为此而生的命令行脚手架工具,它让开发者快速生成一个带基础结构的插件骨架,并在创建过程中通过交互式问答选择需要的功能特性。
版本要求:
inventree-plugin-creator面向 InvenTree1.0.0 及以上版本设计。虽然它也能用于开发早期版本插件,但生成器产生的用户界面(UI)相关特性在旧版本 InvenTree 中无法工作。
工具提供的能力清单
根据 creator.md,该工具覆盖了插件开发的全生命周期:
- 元数据输入:录入插件名称、描述、作者等元信息;
- 许可证选择:提供多种许可证选项,默认 "MIT";
- 功能选择:挑选需要包含的插件特性,如各种 mixin 与前端功能;
- DevOps 集成:可选初始化 Git 版本控制、自动代码格式化(基于 pre-commit)、以及 GitHub / GitLab CI 集成;
- 部署支持:生成可部署到 InvenTree 实例、可发布到 PyPI 的基础插件结构;
- 前端开发:为前端特性搭建开发服务器,支持热重载与构建工具链。
前置要求
开始之前,需要满足两个条件:
- 拥有一套可正常运行的 InvenTree 实例;
- 已经按照官方 devcontainer 开发环境指南 搭建好开发环境(本文示例采用 devcontainer 默认布局,配置文件位于
./dev/config.yaml)。
本文档示例全部使用 Plugin Creator 的默认选项,你可以根据实际需求自定义各步骤的选择。
安装 Plugin Creator
工具通过 Python 包管理器分发,执行:
pip install -U inventree-plugin-creator安装完成后,命令行入口为create-inventree-plugin。
创建插件:交互式脚手架流程
在终端中运行:
create-inventree-plugin命令会进入交互式引导流程,依次完成以下配置。
第一步:插件元数据
首先输入插件的元数据信息(名称、描述、作者等)。这一步直接对应插件类上的元数据属性——从源码看,plugin.py 中的MetaBase基类通过get_meta_value()统一读取NAME/SLUG/TITLE等类属性,并兼容PLUGIN_NAME等旧属性名(使用旧名会触发 DeprecationWarning)。其中SLUG未显式指定时会由名称自动 slugify 生成。
第二步:选择许可证
为插件选择许可证,默认 "MIT",也可选择其他常见开源许可证。许可证信息会被写入插件包的LICENSE文件,并可作为类属性LICENSE提供给 InvenTree(见 plugin.py 的license属性,其回退读取包元数据中的 License 字段)。
第三步:选择插件功能(Mixin)
接下来选择要包含的插件 mixin 类型。InvenTree 后端定义了丰富的 mixin 枚举,见 plugin.py 中的PluginMixinEnum,包括但不限于:
action(动作)、api_call(外部 API 调用)、app(自定义 App)、barcode(条码处理)currencyexchange(汇率)、events(事件监听)、exporter(数据导出)、icon_pack(图标包)labels(标签)、locate(定位)、machine(机器)、mail(邮件)navigation(导航)、notification(通知)、report(报表)、schedule(定时任务)settings(插件设置)、settingscontent、supplier(供应商数据)、statetransition(状态机)urls(URL 路由)、ui(用户界面)、validation(数据校验)、well-known(Well-Known 端点)
每个 mixin 通过MixinBase.add_mixin()注册进插件实例的_mixins字典,并由mixin_enabled()判断是否启用、get_registered_mixins()提供注册信息查询(见 plugin.py)。
若选择
UserInterfaceMixin,混入的是 ui/mixins.py 中定义的UserInterfaceMixin类,其get_ui_features()按feature_type分发到spotlight_action、dashboard、panel、template_editor、template_preview、navigation、primary_action七类注入能力。
第四步:选择前端功能
如果在上一步勾选了UserInterfaceMixin(本例即是如此),工具会继续询问要包含的前端功能:
- Custom dashboard items:为 InvenTree 用户界面创建自定义仪表盘组件;
- Custom panel items:向界面添加自定义面板;
- Custom settings display:为插件创建自定义设置页面。
第五步:Git 与 DevOps 集成
可按需开启 Git 集成:工具会初始化插件仓库,并配置基于 pre-commit 的自动代码格式化;还可以选择配置 CI 集成(GitHub 或 GitLab),让 CI 在代码推送后自动运行测试与检查。
安装插件到 InvenTree(可编辑模式)
创建完成后,插件位于创建过程中指定的目录。以示例插件 "MyCustomPlugin" 为例,验证生成的文件结构:
cd MyCustomPlugin ls -al典型目录结构如下(实际文件取决于你在创建时勾选的功能):
| 文件 / 目录 | 说明 |
|---|---|
| .git | 插件 Git 仓库(选择 Git 集成时生成) |
| .github | GitHub 配置目录(选择 GitHub 集成时生成) |
| .gitlab-ci.yml | GitLab CI 配置文件(选择 GitLab 集成时生成) |
| .gitignore | Git 忽略规则文件 |
| .pre-commit-config.yaml | pre-commit 钩子配置(选择 pre-commit 时生成) |
| .editorconfig | 编辑器统一风格配置 |
| LICENSE | 插件许可证文件 |
| MANIFEST.in | 声明打包时需包含的文件 |
| README.md | 插件说明文档 |
| biome.json | Biome 代码格式化器配置 |
| pyproject.toml | 插件项目配置 |
| setup.cfg | Python 代码格式与 lint 规则 |
| setup.py | 插件安装脚本 |
| frontend/ | 前端代码目录(选择前端功能时生成) |
| my_custom_plugin/ | 插件主目录(目录名与创建时填写的插件名对应) |
接下来需要在当前激活的 Python 环境中安装插件,InvenTree 才能发现并加载它。开发阶段推荐使用editable install(可编辑安装),这样修改插件代码后无需重新安装即可生效:
pip install -e .安装后可用pip show验证:
pip show inventree-my-custom-plugin从源码角度看,plugin.py 的is_editable()类方法通过检查{包名}-*.dist-info目录来判断插件是否为可编辑安装,插件注册表据此识别本地开发插件。
激活插件
插件安装完毕后,需要在 InvenTree 实例中将其激活。若服务器尚未运行,先启动开发服务器:
invoke dev.server然后访问插件管理页面(默认地址http://localhost:8000/web/settings/admin/plugin),在插件列表中点击对应插件的Activate按钮完成激活。
激活成功后,插件即可参与 InvenTree 运行时流程。插件实例的激活状态由MetaBase.is_active()判定:若插件被标记为 mandatory 则恒为激活,否则查询PluginConfig.is_active()(见 plugin.py)。
前端功能开发:后端重定向与热重载
本例创建的插件包含前端功能。生产环境中,前端代码会被编译并以静态文件形式由 InvenTree 服务器托管;但在开发阶段,更实用的做法是运行一个提供热重载(hot reloading)的开发服务器。
后端配置:将静态请求重定向到开发服务器
要让 InvenTree 后端把该插件的前端请求转发到开发服务器,需要在服务器配置文件中添加以下配置(使用默认 devcontainer 布局时为./dev/config.yaml):
plugin_dev: slug: 'my-custom-plugin' # 替换为你的插件 slug host: "http://localhost:5174"注意:修改配置文件后必须重启 InvenTree 服务器才能生效。
这段配置让 InvenTree 将该插件的静态文件请求转发到 5174 端口上运行的开发服务器——该行为仅在开发模式下生效,生产环境不会使用。其底层实现位于 settings.py:PLUGIN_DEV_SLUG读取配置键plugin_dev.slug,PLUGIN_DEV_HOST读取plugin_dev.host(默认值http://localhost:5174)。随后 plugin.py 的plugin_static_file()在满足DEBUG开启、PLUGIN_DEV_HOST/PLUGIN_DEV_SLUG均已设置、且插件 slug 匹配这三个条件时,会把资源 URL 拼接为{PLUGIN_DEV_HOST}/src/{path},并将.js扩展名替换为.tsx,直接指向 Vite 开发服务器的源码文件。
启动前端开发服务器
进入frontend目录安装依赖并启动开发服务器:
cd frontend npm install npm run dev启动成功后,开发服务器运行在 5174 端口:
验证:查看自定义面板
脚手架默认代码提供了一个显示在part 详情页上的自定义 "panel"。在 InvenTree 实例中打开任意零件详情页,即可看到该自定义面板:
这一能力正是由UserInterfaceMixin的get_ui_panels()提供的。可以参考仓库内置示例 user_interface_sample.py:面板通过key、title、source、icon、context字段描述,其中source指向plugin_static_file()解析出的 JS 文件(可带:renderFunction指定渲染函数),context会把服务端数据(如零件名、版本号、随机值)传给前端渲染函数;面板还可结合SettingsMixin的设置项和request.user.is_superuser按条件动态返回。
编辑插件代码
后端代码
插件后端代码位于my_custom_plugin/目录,主要逻辑集中在my_custom_plugin/core.py中。若创建时选择了其他 mixin 类型,该目录下还会生成与之对应的额外文件。
由于插件以可编辑模式安装,修改后端代码后无需重新安装即可在 InvenTree 实例中立即生效。
调试服务器说明:后端代码的实时重载仅在 InvenTree 服务器以 debug 模式运行时有效;生产模式下需重启服务器才能看到变更。
前端代码
前端代码位于frontend/src目录,自定义 part 详情页面板实现在./frontend/src/Panel.tsx中,可修改该文件调整面板内容与行为。开发服务器运行期间,前端修改通过React Fast Refresh实时反映到浏览器,无需每次重建前端。
React Fast Refresh 注意事项:插件模块中所有导出 React 组件的导出名必须以大写字母开头,否则 React Fast Refresh 会退化为整页刷新;此外,任何被 Python 端引用的 render 函数名也必须大写。
构建与发布插件
上述流程面向开发阶段。开发完成后,需要构建插件用于分发。
CI 构建:若在创建插件时配置了 CI 集成,推送代码后 CI 服务器会自动构建插件,这是推荐的构建与分发方式。
编译前端资源
前端资源在分发前必须先编译。编译产物(主要是.js文件)需要随插件一并分发,由 InvenTree 服务器静态托管——因此编译文件需放入./my_custom_plugin/static目录,前端build步骤会自动完成这一放置:
cd frontend npm run build后端在收集插件静态文件时,会将每个插件的static目录复制到静态存储的plugins/{slug}/前缀下(见 staticfiles.py)。此外,plugin.py 的hashed_file_lookup()支持读取插件静态目录中.vite/manifest.json(由 Plugin Creator 前端框架生成),从而定位带哈希文件名(如file-abc123.js)的资源以支持缓存破坏(cache busting)——这正是编译产物能够正确被引用的机制。
构建 Python 包
前端资源编译完成后,即可构建可分发的 Python 包:
python -m build注意:请在插件顶层目录(即包含
setup.py的目录)中执行该命令。
构建成功后,会产出可供其他 InvenTree 实例安装的分发包。
发布到 PyPI
构建产物可发布到 PyPI(或其他包索引),使插件能被远程安装到其他 InvenTree 部署中。PyPI 发布细节不在本文范围内,可参考 Python Packaging User Guide(Python 打包用户指南)中的打包项目教程。
自动化发布:若在创建插件时配置了 CI 集成,当创建新 release 时 CI 服务器会自动将插件发布到 PyPI,只需确保在 CI 环境中配置好必要的凭据。
进一步阅读
本文展示了插件开发的基础骨架。如需更复杂的开发示例,可继续阅读 插件开发实战 Walkthrough,该指南会带你逐步实现一个在零件详情页展示附件图片轮播的自定义面板,可作为深入学习 InvenTree 插件前后端联调的进阶教程。
【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考