更新插件组件文档,调整多个组件以支持关闭功能,增强用户交互体验,并修正配置示例以反映最新的代码结构和依赖关系。

This commit is contained in:
jxxghp
2025-05-07 08:21:44 +08:00
parent d3a6703a77
commit d3f9c04209
8 changed files with 85 additions and 296 deletions

View File

@@ -2,8 +2,6 @@
本文档提供了针对 MoviePilot 项目中使用模块联邦时可能遇到的常见问题及解决方案。
关联阅读后端插件开发文档:[第三方插件开发说明](https://github.com/jxxghp/MoviePilot-Plugins/blob/main/README.md)
## 远程组件注册机制
MoviePilot 使用自动注册机制来加载远程组件:
@@ -104,90 +102,9 @@ localStorage.setItem('debug', 'vite:*')
创建一个独立的简单页面来测试插件组件,排除主应用的干扰因素。
## 最佳实践
### 插件组件项目配置
```js
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
vue(),
federation({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./PluginComponent': './src/App.vue',
},
shared: {
vue: {
singleton: true,
requiredVersion: false
}
}
})
],
build: {
target: 'esnext',
minify: false, // 开发阶段禁用最小化,方便调试
cssCodeSplit: false,
rollupOptions: {
output: {
minifyInternalExports: false
}
}
}
})
```
### 插件组件代码
```vue
<template>
<div class="plugin-container">
<!-- 组件内容 -->
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
// 向主应用发送事件
const emit = defineEmits(['action'])
// 初始化逻辑...
// 通知主应用
function notifyHost() {
emit('action')
}
</script>
```
### 显式依赖声明
在插件组件的 `package.json` 中准确声明所有依赖:
```json
{
"dependencies": {
"vue": "^3.3.4"
},
"devDependencies": {
"@originjs/vite-plugin-federation": "^1.3.5",
"@vitejs/plugin-vue": "^4.4.0",
"vite": "^5.0.0"
}
}
```
## 其他资源
- [MoviePilot 插件组件示例](../examples/plugin-component/)
- [Vite 模块联邦插件文档](https://github.com/originjs/vite-plugin-federation)
- [Vite 官方文档](https://vitejs.dev/guide/build.html)
- [Origin.js 模块联邦示例](https://github.com/originjs/vite-plugin-federation/tree/main/packages/examples)
- [MoviePilot 插件组件示例](../examples/plugin-component/)

View File

@@ -4,6 +4,9 @@
MoviePilot前端采用模块联邦(Module Federation)技术实现插件的动态加载和集成。本文档详细说明如何开发符合要求的远程模块以便在MoviePilot中作为插件使用。
关联阅读后端插件开发文档:[第三方插件开发说明](https://github.com/jxxghp/MoviePilot-Plugins/blob/main/README.md)
## 2. 技术要求
- Node.js 16+
@@ -33,13 +36,7 @@ npm create vite@latest my-plugin -- --template vue-ts
cd my-plugin
# 安装依赖
npm install
# 安装模块联邦插件
npm install @originjs/vite-plugin-federation --save-dev
# 安装Vuetify(可选)
npm install vuetify
yarn
```
### 配置vite.config.ts
@@ -53,31 +50,27 @@ export default defineConfig({
plugins: [
vue(),
federation({
name: 'my_plugin', // 插件名称建议与插件ID保持一致
name: 'LogsClean',
filename: 'remoteEntry.js',
exposes: {
'./Page': './src/components/Page.vue',
'./Config': './src/components/Config.vue',
'./Dashboard': './src/components/Dashboard.vue',
},
shared: {
vue: { requiredVersion: false },
vuetify: { requiredVersion: false }
}
shared: ['vue', 'vuetify'],
format: 'esm'
})
],
build: {
target: 'esnext', // 必须设置为esnext以支持顶层await
minify: false, // 开发阶段建议关闭混淆
cssCodeSplit: false,
rollupOptions: {
output: {
format: 'esm', // 必须使用ESM格式
entryFileNames: '[name].js',
chunkFileNames: '[name].js',
}
}
}
},
server: {
port: 5001, // 使用不同于主应用的端口
cors: true, // 启用CORS
origin: 'http://localhost:5001'
},
})
```
@@ -88,7 +81,15 @@ export default defineConfig({
```vue
<script setup lang="ts">
// 自定义事件,用于通知主应用刷新数据
const emit = defineEmits(['action', 'switch'])
const emit = defineEmits(['action', 'switch', 'close'])
// 接收API对象
const props = defineProps({
api: {
type: any,
default: () => {}
}
})
// 页面逻辑代码...
@@ -110,7 +111,7 @@ function notifyClose() {
<template>
<div class="plugin-page">
<!-- 插件详情页面内容 -->
<!-- 插件详情页面操作按钮 -->
<v-btn @click="notifyRefresh">刷新数据</v-btn>
<v-btn @click="notifySwitch">配置插件</v-btn>
<v-btn @click="notifyClose">关闭页面</v-btn>
@@ -122,11 +123,15 @@ function notifyClose() {
```vue
<script setup lang="ts">
// 接收初始配置
// 接收初始配置和API对象
const props = defineProps({
initialConfig: {
type: Object,
default: () => ({})
},
api: {
type: any,
default: () => {}
}
})
@@ -134,7 +139,7 @@ const props = defineProps({
const config = ref({...props.initialConfig})
// 自定义事件,用于保存配置
const emit = defineEmits(['save'])
const emit = defineEmits(['save', 'close', 'switch'])
// 保存配置
function saveConfig() {
@@ -206,10 +211,21 @@ const props = defineProps({
### 构建项目
```bash
npm run build
yarn build
```
将生成的dist文件夹上传到插件后端目录下默认为`dist/assets`),在插件的后端代码中,实现以下方法来集成远程组件:
```python
def get_render_mode() -> Tuple[str, str]:
"""
获取插件渲染模式
:return: 1、渲染模式支持vue/vuetify默认vuetify
:return: 2、组件路径默认 dist/assets
"""
return "vue", "dist/assets"
```
将生成的dist文件夹上传到插件后端并配置插件后端API路径。
## 7. 调试与排错
@@ -232,9 +248,9 @@ npm run build
4. **"Top-level await is not available"**
- 确保`build.target`设置为`esnext`
## 9. 高级配置
## 8. 高级配置
### 9.1 CSS隔离
### 8.1 CSS隔离
为防止样式冲突建议使用CSS Modules或scoped样式
@@ -244,7 +260,7 @@ npm run build
</style>
```
### 9.2 共享更多依赖
### 8.2 共享更多依赖
如果您的插件需要共享更多依赖可以扩展shared配置
@@ -257,7 +273,7 @@ shared: {
}
```
### 9.3 开发环境测试
### 8.3 开发环境测试
开发期间可以使用以下配置在本地测试:
@@ -272,11 +288,12 @@ export default defineConfig({
})
```
## 10. 示例代码
## 9. 示例代码
- [插件远程组件示例](../examples/plugin-component/) - 开发插件组件的完整示例项目
- [模块联邦问题排查指南](./federation-troubleshooting.md) - 常见问题排查
## 11. 参考资料
## 10. 参考资料
- [Vite Plugin Federation](https://github.com/originjs/vite-plugin-federation)
- [Vue 3官方文档](https://vuejs.org/)