mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 15:36:49 +08:00
添加 @originjs/vite-plugin-federation 依赖,并在多个组件中实现远程组件加载功能
This commit is contained in:
Vendored
+3
-1
@@ -328,7 +328,7 @@ declare global {
|
|||||||
// for type re-export
|
// for type re-export
|
||||||
declare global {
|
declare global {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||||
import('vue')
|
import('vue')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +356,7 @@ declare module 'vue' {
|
|||||||
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
|
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
|
||||||
readonly createProjection: UnwrapRef<typeof import('@vueuse/math')['createProjection']>
|
readonly createProjection: UnwrapRef<typeof import('@vueuse/math')['createProjection']>
|
||||||
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
|
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
|
||||||
|
readonly createRef: UnwrapRef<typeof import('@vueuse/core')['createRef']>
|
||||||
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
|
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
|
||||||
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
|
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
|
||||||
readonly createTemplatePromise: UnwrapRef<typeof import('@vueuse/core')['createTemplatePromise']>
|
readonly createTemplatePromise: UnwrapRef<typeof import('@vueuse/core')['createTemplatePromise']>
|
||||||
@@ -490,6 +491,7 @@ declare module 'vue' {
|
|||||||
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
|
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
|
||||||
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
|
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
|
||||||
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
|
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
|
||||||
|
readonly useCountdown: UnwrapRef<typeof import('@vueuse/core')['useCountdown']>
|
||||||
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
|
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
|
||||||
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
|
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
|
||||||
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
|
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
|
||||||
|
|||||||
Vendored
+1
@@ -2,6 +2,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// Generated by unplugin-vue-components
|
// Generated by unplugin-vue-components
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
// biome-ignore lint: disable
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
"@iconify/tools": "^4.0.4",
|
"@iconify/tools": "^4.0.4",
|
||||||
"@iconify/vue": "^4.3.0",
|
"@iconify/vue": "^4.3.0",
|
||||||
"@intlify/unplugin-vue-i18n": "^6.0.3",
|
"@intlify/unplugin-vue-i18n": "^6.0.3",
|
||||||
|
"@originjs/vite-plugin-federation": "^1.4.1",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/mousetrap": "^1.6.15",
|
"@types/mousetrap": "^1.6.15",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useToast } from 'vue-toast-notification'
|
|||||||
import FormRender from '../render/FormRender.vue'
|
import FormRender from '../render/FormRender.vue'
|
||||||
import ProgressDialog from '../dialog/ProgressDialog.vue'
|
import ProgressDialog from '../dialog/ProgressDialog.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { loadRemoteComponent, clearRemoteComponentCache } from '@/utils/remoteFederationLoader'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -51,32 +52,12 @@ const vueComponentUrl = ref<string | null>(null)
|
|||||||
// Vue 模式:动态加载的组件
|
// Vue 模式:动态加载的组件
|
||||||
const dynamicComponent = computed(() => {
|
const dynamicComponent = computed(() => {
|
||||||
if (renderMode.value === 'vue' && vueComponentUrl.value) {
|
if (renderMode.value === 'vue' && vueComponentUrl.value) {
|
||||||
const url = vueComponentUrl.value
|
return loadRemoteComponent(vueComponentUrl.value, {
|
||||||
return defineAsyncComponent(() =>
|
onError: error => {
|
||||||
api
|
console.error(`加载插件组件失败: ${vueComponentUrl.value}`, error)
|
||||||
.get(url)
|
$toast.error(`加载插件组件失败: ${error.message || '未知错误'}`)
|
||||||
.then((response: any) => {
|
},
|
||||||
if (response) {
|
})
|
||||||
const blob = new Blob([response.data], { type: 'text/javascript' })
|
|
||||||
const blobUrl = URL.createObjectURL(blob)
|
|
||||||
return import(/* @vite-ignore */ blobUrl)
|
|
||||||
} else {
|
|
||||||
return { render: () => h('div', '组件加载失败: 未读取到文件数据') }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(module => {
|
|
||||||
if (module.default) {
|
|
||||||
return module.default
|
|
||||||
} else {
|
|
||||||
console.error(`无法从 ${url} 加载默认导出的 Vue 组件`)
|
|
||||||
return { render: () => h('div', '组件加载失败: 无默认导出') }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error(`无法加载插件组件: ${url}`, err)
|
|
||||||
return { render: () => h('div', `组件加载失败:${err}`) }
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
@@ -88,6 +69,11 @@ async function loadPluginUIData() {
|
|||||||
pluginFormItems = []
|
pluginFormItems = []
|
||||||
pluginConfigForm.value = {}
|
pluginConfigForm.value = {}
|
||||||
renderMode.value = 'vuetify'
|
renderMode.value = 'vuetify'
|
||||||
|
|
||||||
|
// 如果存在旧的组件URL,清除其缓存
|
||||||
|
if (vueComponentUrl.value) {
|
||||||
|
clearRemoteComponentCache(vueComponentUrl.value)
|
||||||
|
}
|
||||||
vueComponentUrl.value = null
|
vueComponentUrl.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -151,6 +137,13 @@ async function savePluginConf() {
|
|||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await loadPluginUIData()
|
await loadPluginUIData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 组件卸载时清理资源
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (vueComponentUrl.value) {
|
||||||
|
clearRemoteComponentCache(vueComponentUrl.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VDialog scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { Plugin } from '@/api/types'
|
|||||||
import PageRender from '@/components/render/PageRender.vue'
|
import PageRender from '@/components/render/PageRender.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
|
import { loadRemoteComponent, clearRemoteComponentCache } from '@/utils/remoteFederationLoader'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -38,32 +39,12 @@ let pluginPageItems = ref([])
|
|||||||
// Vue 模式:动态加载的组件
|
// Vue 模式:动态加载的组件
|
||||||
const dynamicComponent = computed(() => {
|
const dynamicComponent = computed(() => {
|
||||||
if (renderMode.value === 'vue' && vueComponentUrl.value) {
|
if (renderMode.value === 'vue' && vueComponentUrl.value) {
|
||||||
const url = vueComponentUrl.value
|
return loadRemoteComponent(vueComponentUrl.value, {
|
||||||
return defineAsyncComponent(() =>
|
onError: error => {
|
||||||
api
|
console.error(`加载插件组件失败: ${vueComponentUrl.value}`, error)
|
||||||
.get(url)
|
$toast.error(`加载插件组件失败: ${error.message || '未知错误'}`)
|
||||||
.then((response: any) => {
|
},
|
||||||
if (response) {
|
})
|
||||||
const blob = new Blob([response.data], { type: 'text/javascript' })
|
|
||||||
const blobUrl = URL.createObjectURL(blob)
|
|
||||||
return import(/* @vite-ignore */ blobUrl)
|
|
||||||
} else {
|
|
||||||
return { render: () => h('div', '组件加载失败: 未读取到文件数据') }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(module => {
|
|
||||||
if (module.default) {
|
|
||||||
return module.default
|
|
||||||
} else {
|
|
||||||
console.error(`无法从 ${url} 加载默认导出的 Vue 组件`)
|
|
||||||
return { render: () => h('div', '组件加载失败: 无默认导出') }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error(`无法加载插件组件: ${url}`, err)
|
|
||||||
return { render: () => h('div', `组件加载失败:${err}`) }
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
@@ -73,6 +54,11 @@ async function loadPluginUIData() {
|
|||||||
isRefreshed.value = false
|
isRefreshed.value = false
|
||||||
pluginPageItems.value = []
|
pluginPageItems.value = []
|
||||||
renderMode.value = 'vuetify'
|
renderMode.value = 'vuetify'
|
||||||
|
|
||||||
|
// 如果存在旧的组件URL,清除其缓存
|
||||||
|
if (vueComponentUrl.value) {
|
||||||
|
clearRemoteComponentCache(vueComponentUrl.value)
|
||||||
|
}
|
||||||
vueComponentUrl.value = null
|
vueComponentUrl.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -105,6 +91,13 @@ function handleAction() {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadPluginUIData()
|
loadPluginUIData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 组件卸载时清理资源
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (vueComponentUrl.value) {
|
||||||
|
clearRemoteComponentCache(vueComponentUrl.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import MediaServerPlaying from '@/views/dashboard/MediaServerPlaying.vue'
|
|||||||
import DashboardRender from '@/components/render/DashboardRender.vue'
|
import DashboardRender from '@/components/render/DashboardRender.vue'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { loadRemoteComponent, clearRemoteComponentCache } from '@/utils/remoteFederationLoader'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -36,30 +37,11 @@ const pluginRenderMode = computed(() => props.config?.render_mode || 'vuetify')
|
|||||||
const dynamicPluginComponent = computed(() => {
|
const dynamicPluginComponent = computed(() => {
|
||||||
// 确保 config 存在并且 component_url 也存在
|
// 确保 config 存在并且 component_url 也存在
|
||||||
if (pluginRenderMode.value === 'vue' && props.config?.component_url) {
|
if (pluginRenderMode.value === 'vue' && props.config?.component_url) {
|
||||||
const url = props.config?.component_url
|
return loadRemoteComponent(props.config.component_url, {
|
||||||
return defineAsyncComponent(() =>
|
onError: error => {
|
||||||
api
|
console.error(`加载插件组件失败: ${props.config?.component_url}`, error)
|
||||||
.get(url)
|
},
|
||||||
.then((response: any) => {
|
})
|
||||||
if (response) {
|
|
||||||
const blob = new Blob([response.data], { type: 'text/javascript' })
|
|
||||||
const blobUrl = URL.createObjectURL(blob)
|
|
||||||
return import(/* @vite-ignore */ blobUrl)
|
|
||||||
} else {
|
|
||||||
return { render: () => h('div', '组件加载失败: 未读取到文件数据') }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(module => {
|
|
||||||
if (module.default) {
|
|
||||||
return module.default
|
|
||||||
} else {
|
|
||||||
return { render: () => h('div', '组件加载失败: 无默认导出') }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return { render: () => h('div', '组件加载失败') }
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
@@ -67,6 +49,11 @@ const dynamicPluginComponent = computed(() => {
|
|||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 组件卸载时禁用刷新状态
|
// 组件卸载时禁用刷新状态
|
||||||
emit('update:refreshStatus', false)
|
emit('update:refreshStatus', false)
|
||||||
|
|
||||||
|
// 清理远程组件缓存
|
||||||
|
if (pluginRenderMode.value === 'vue' && props.config?.component_url) {
|
||||||
|
clearRemoteComponentCache(props.config.component_url)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* 模块联邦动态加载器
|
||||||
|
* 用于动态加载远程组件
|
||||||
|
*/
|
||||||
|
import { defineAsyncComponent, type Component } from 'vue'
|
||||||
|
import api from '@/api'
|
||||||
|
|
||||||
|
// 远程组件加载状态
|
||||||
|
interface RemoteModuleState {
|
||||||
|
loading: boolean
|
||||||
|
loaded: boolean
|
||||||
|
module: any
|
||||||
|
error: Error | null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已加载组件的缓存
|
||||||
|
const loadedRemotes: Record<string, RemoteModuleState> = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取和初始化远程组件
|
||||||
|
* @param remoteUrl 远程组件URL
|
||||||
|
* @param options 组件选项
|
||||||
|
* @returns 异步组件
|
||||||
|
*/
|
||||||
|
export function loadRemoteComponent(
|
||||||
|
remoteUrl: string,
|
||||||
|
options: {
|
||||||
|
timeout?: number
|
||||||
|
onError?: (error: Error) => void
|
||||||
|
} = {},
|
||||||
|
): Component {
|
||||||
|
const { timeout = 30000, onError } = options
|
||||||
|
|
||||||
|
// 创建异步组件
|
||||||
|
return defineAsyncComponent({
|
||||||
|
loader: async () => {
|
||||||
|
try {
|
||||||
|
// 检查缓存
|
||||||
|
if (loadedRemotes[remoteUrl]?.loaded) {
|
||||||
|
return loadedRemotes[remoteUrl].module
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记加载状态
|
||||||
|
if (!loadedRemotes[remoteUrl]) {
|
||||||
|
loadedRemotes[remoteUrl] = {
|
||||||
|
loading: false,
|
||||||
|
loaded: false,
|
||||||
|
module: null,
|
||||||
|
error: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果正在加载,等待加载完成
|
||||||
|
if (loadedRemotes[remoteUrl].loading) {
|
||||||
|
while (loadedRemotes[remoteUrl].loading && !loadedRemotes[remoteUrl].loaded) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100))
|
||||||
|
}
|
||||||
|
if (loadedRemotes[remoteUrl].error) {
|
||||||
|
throw loadedRemotes[remoteUrl].error
|
||||||
|
}
|
||||||
|
return loadedRemotes[remoteUrl].module
|
||||||
|
}
|
||||||
|
|
||||||
|
loadedRemotes[remoteUrl].loading = true
|
||||||
|
|
||||||
|
// 获取远程组件JS
|
||||||
|
const response = await api.get(remoteUrl)
|
||||||
|
if (!response) {
|
||||||
|
throw new Error('无法加载远程组件:请求无响应或响应无数据')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建Blob URL并动态导入
|
||||||
|
const blob = new Blob([response as any], { type: 'text/javascript' })
|
||||||
|
const blobUrl = URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// 动态导入模块
|
||||||
|
const moduleExports = await import(/* @vite-ignore */ blobUrl)
|
||||||
|
|
||||||
|
// 清理Blob URL
|
||||||
|
URL.revokeObjectURL(blobUrl)
|
||||||
|
|
||||||
|
// 获取默认导出
|
||||||
|
if (!moduleExports.default) {
|
||||||
|
throw new Error('远程组件没有默认导出')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新缓存
|
||||||
|
loadedRemotes[remoteUrl].module = moduleExports.default
|
||||||
|
loadedRemotes[remoteUrl].loaded = true
|
||||||
|
loadedRemotes[remoteUrl].loading = false
|
||||||
|
|
||||||
|
return moduleExports.default
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(`加载远程组件失败: ${remoteUrl}`, error)
|
||||||
|
loadedRemotes[remoteUrl].error = error
|
||||||
|
loadedRemotes[remoteUrl].loading = false
|
||||||
|
|
||||||
|
// 调用错误处理回调
|
||||||
|
if (onError) onError(error)
|
||||||
|
|
||||||
|
// 返回一个简单的错误组件
|
||||||
|
return {
|
||||||
|
render: () =>
|
||||||
|
h('div', { class: 'text-error pa-4 text-center' }, `组件加载失败: ${error.message || '未知错误'}`),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timeout,
|
||||||
|
// 可以定义加载中和错误状态的组件
|
||||||
|
loadingComponent: {
|
||||||
|
render: () => h('div', { class: 'text-center pa-4' }, '加载组件中...'),
|
||||||
|
},
|
||||||
|
errorComponent: {
|
||||||
|
render: () => h('div', { class: 'text-error pa-4 text-center' }, '组件加载失败'),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除缓存的组件
|
||||||
|
export function clearRemoteComponentCache(remoteUrl?: string) {
|
||||||
|
if (remoteUrl) {
|
||||||
|
delete loadedRemotes[remoteUrl]
|
||||||
|
} else {
|
||||||
|
// 清除所有缓存
|
||||||
|
Object.keys(loadedRemotes).forEach(key => {
|
||||||
|
delete loadedRemotes[key]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-15
@@ -8,6 +8,7 @@ import vuetify from 'vite-plugin-vuetify'
|
|||||||
import { VitePWA } from 'vite-plugin-pwa'
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
|
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
|
||||||
import { resolve } from 'node:path'
|
import { resolve } from 'node:path'
|
||||||
|
import federation from '@originjs/vite-plugin-federation'
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -31,6 +32,13 @@ export default defineConfig({
|
|||||||
VueI18n({
|
VueI18n({
|
||||||
include: [resolve(__dirname, 'src/locales/*.ts')],
|
include: [resolve(__dirname, 'src/locales/*.ts')],
|
||||||
}),
|
}),
|
||||||
|
federation({
|
||||||
|
name: 'host',
|
||||||
|
remotes: {
|
||||||
|
// 这里我们会动态添加远程组件,所以不预设remotes
|
||||||
|
},
|
||||||
|
shared: ['vue', 'vuetify'],
|
||||||
|
}),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
injectRegister: 'script',
|
injectRegister: 'script',
|
||||||
registerType: 'autoUpdate',
|
registerType: 'autoUpdate',
|
||||||
@@ -116,8 +124,8 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': '电影订阅',
|
'name': '探索',
|
||||||
'url': './subscribe/movie',
|
'url': './discover',
|
||||||
'icons': [
|
'icons': [
|
||||||
{
|
{
|
||||||
'src': './clock-icon-192x192.png',
|
'src': './clock-icon-192x192.png',
|
||||||
@@ -127,19 +135,8 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': '电视剧订阅',
|
'name': '更多',
|
||||||
'url': './subscribe/tv',
|
'url': './apps',
|
||||||
'icons': [
|
|
||||||
{
|
|
||||||
'src': './clock-icon-192x192.png',
|
|
||||||
'sizes': '192x192',
|
|
||||||
'type': 'image/png',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': '设置',
|
|
||||||
'url': './setting',
|
|
||||||
'icons': [
|
'icons': [
|
||||||
{
|
{
|
||||||
'src': './cog-icon-192x192.png',
|
'src': './cog-icon-192x192.png',
|
||||||
|
|||||||
@@ -1428,7 +1428,7 @@
|
|||||||
"@jridgewell/gen-mapping" "^0.3.5"
|
"@jridgewell/gen-mapping" "^0.3.5"
|
||||||
"@jridgewell/trace-mapping" "^0.3.25"
|
"@jridgewell/trace-mapping" "^0.3.25"
|
||||||
|
|
||||||
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
|
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||||
@@ -1516,6 +1516,14 @@
|
|||||||
unimport "^5.0.0"
|
unimport "^5.0.0"
|
||||||
untyped "^2.0.0"
|
untyped "^2.0.0"
|
||||||
|
|
||||||
|
"@originjs/vite-plugin-federation@^1.4.1":
|
||||||
|
version "1.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@originjs/vite-plugin-federation/-/vite-plugin-federation-1.4.1.tgz#e6abc8f18f2cf82783eb87853f4d03e6358b43c2"
|
||||||
|
integrity sha512-Uo08jW5pj1t58OUKuZNkmzcfTN2pqeVuAWCCiKf/75/oll4Efq4cHOqSE1FXMlvwZNGDziNdDyBbQ5IANem3CQ==
|
||||||
|
dependencies:
|
||||||
|
estree-walker "^3.0.2"
|
||||||
|
magic-string "^0.27.0"
|
||||||
|
|
||||||
"@parcel/watcher-android-arm64@2.5.1":
|
"@parcel/watcher-android-arm64@2.5.1":
|
||||||
version "2.5.1"
|
version "2.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz#507f836d7e2042f798c7d07ad19c3546f9848ac1"
|
resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz#507f836d7e2042f798c7d07ad19c3546f9848ac1"
|
||||||
@@ -3989,7 +3997,7 @@ estree-walker@^2.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||||
|
|
||||||
estree-walker@^3.0.3:
|
estree-walker@^3.0.2, estree-walker@^3.0.3:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
|
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
|
||||||
integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
|
integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
|
||||||
@@ -5260,6 +5268,13 @@ magic-string@^0.25.0, magic-string@^0.25.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
sourcemap-codec "^1.4.8"
|
sourcemap-codec "^1.4.8"
|
||||||
|
|
||||||
|
magic-string@^0.27.0:
|
||||||
|
version "0.27.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
|
||||||
|
integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/sourcemap-codec" "^1.4.13"
|
||||||
|
|
||||||
magic-string@^0.30.11, magic-string@^0.30.17:
|
magic-string@^0.30.11, magic-string@^0.30.17:
|
||||||
version "0.30.17"
|
version "0.30.17"
|
||||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
||||||
@@ -6703,7 +6718,16 @@ std-env@^3.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1"
|
resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1"
|
||||||
integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==
|
integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.3:
|
"string-width-cjs@npm:string-width@^4.2.0":
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
|
string-width@^4.1.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
@@ -6788,7 +6812,14 @@ stringify-object@^3.3.0:
|
|||||||
is-obj "^1.0.1"
|
is-obj "^1.0.1"
|
||||||
is-regexp "^1.0.0"
|
is-regexp "^1.0.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
|||||||
Reference in New Issue
Block a user