|
1 | 1 | import type { App } from 'vue'; |
2 | 2 | import { warn } from '/@/utils/log'; |
3 | 3 | import { registerDynamicRouter } from '/@/utils/monorepo/dynamicRouter'; |
4 | | -// 引入模块 |
5 | | -import PACKAGE_JEECG_ONLINE from '@jeecg/online'; |
6 | | -import PACKAGE_JEECG_AIFLOW from '@jeecg/aiflow'; |
| 4 | +import { add } from '/@/components/Form/src/componentMap'; |
7 | 5 |
|
8 | | -export function registerPackages(app: App) { |
9 | | - use(app, PACKAGE_JEECG_ONLINE); |
10 | | - use(app, PACKAGE_JEECG_AIFLOW); |
11 | | -} |
| 6 | +// 懒加载模块配置(按需加载,访问相关路由时才加载对应包) |
| 7 | +const lazyPackages = [ |
| 8 | + { name: '@jeecg/online', importer: () => import('@jeecg/online') }, |
| 9 | + { name: '@jeecg/aiflow', importer: () => import('@jeecg/aiflow') }, |
| 10 | +]; |
| 11 | + |
| 12 | +let appInstance: App | null = null; |
12 | 13 |
|
13 | 14 | // noinspection JSUnusedGlobalSymbols |
14 | 15 | const installOptions = { |
15 | 16 | baseImport, |
16 | 17 | }; |
17 | 18 |
|
18 | | -/** 注册模块 */ |
19 | | -function use(app: App, pkg) { |
20 | | - app.use(pkg, installOptions); |
21 | | - registerDynamicRouter(pkg.getViews); |
| 19 | +export function registerPackages(app: App) { |
| 20 | + // 仅保存 app 实例,不立即加载模块 |
| 21 | + appInstance = app; |
| 22 | +} |
| 23 | + |
| 24 | +/** 已加载的包缓存 */ |
| 25 | +const loadedPackages = new Map<string, any>(); |
| 26 | +/** 正在加载的包 Promise 缓存(防止重复加载) */ |
| 27 | +const loadingPromises = new Map<string, Promise<any>>(); |
| 28 | + |
| 29 | +/** |
| 30 | + * 按需加载包并注册 |
| 31 | + */ |
| 32 | +async function ensurePackageLoaded(pkgConfig: typeof lazyPackages[number]) { |
| 33 | + const { name, importer } = pkgConfig; |
| 34 | + if (loadedPackages.has(name)) { |
| 35 | + return loadedPackages.get(name); |
| 36 | + } |
| 37 | + if (!loadingPromises.has(name)) { |
| 38 | + const promise = importer().then((pkg) => { |
| 39 | + const mod = pkg.default || pkg; |
| 40 | + if (appInstance) { |
| 41 | + appInstance.use(mod, installOptions); |
| 42 | + registerDynamicRouter(mod.getViews); |
| 43 | + } |
| 44 | + loadedPackages.set(name, mod); |
| 45 | + loadingPromises.delete(name); |
| 46 | + return mod; |
| 47 | + }); |
| 48 | + loadingPromises.set(name, promise); |
| 49 | + } |
| 50 | + return loadingPromises.get(name); |
| 51 | +} |
| 52 | + |
| 53 | +/** |
| 54 | + * 根据 component 路径关键字匹配优先加载的包 |
| 55 | + */ |
| 56 | +function getMatchedPackage(component: string): typeof lazyPackages[number] | null { |
| 57 | + const lc = component.toLowerCase(); |
| 58 | + for (const pkgConfig of lazyPackages) { |
| 59 | + // 从包名中提取关键字,如 @jeecg/online -> online, @jeecg/aiflow -> aiflow |
| 60 | + const keyword = pkgConfig.name.split('/').pop()!; |
| 61 | + if (lc.includes(keyword)) { |
| 62 | + return pkgConfig; |
| 63 | + } |
| 64 | + } |
| 65 | + return null; |
| 66 | +} |
| 67 | + |
| 68 | +/** |
| 69 | + * 从指定包中查找组件 |
| 70 | + */ |
| 71 | +async function findComponentInPackage(pkgConfig: typeof lazyPackages[number], component: string): Promise<(() => Promise<Recordable>) | null> { |
| 72 | + try { |
| 73 | + const mod = await ensurePackageLoaded(pkgConfig); |
| 74 | + const views = mod.getViews(); |
| 75 | + for (const key of Object.keys(views)) { |
| 76 | + const k = key.replace('./src/views', ''); |
| 77 | + const startFlag = component.startsWith('/'); |
| 78 | + const endFlag = component.endsWith('.vue') || component.endsWith('.tsx'); |
| 79 | + const startIndex = startFlag ? 0 : 1; |
| 80 | + const lastIndex = endFlag ? k.length : k.lastIndexOf('.'); |
| 81 | + if (k.substring(startIndex, lastIndex) === component) { |
| 82 | + return views[key]; |
| 83 | + } |
| 84 | + } |
| 85 | + } catch (e) { |
| 86 | + // 包不存在或加载失败,跳过 |
| 87 | + } |
| 88 | + return null; |
| 89 | +} |
| 90 | + |
| 91 | +/** |
| 92 | + * 按需加载包组件:当路由匹配不到本地组件时调用 |
| 93 | + * 根据 component 路径中的关键字优先匹配对应包,避免无意义的遍历 |
| 94 | + */ |
| 95 | +export async function loadPackageComponent(component: string): Promise<(() => Promise<Recordable>) | null> { |
| 96 | + // 优先根据关键字精准匹配包 |
| 97 | + const matched = getMatchedPackage(component); |
| 98 | + if (matched) { |
| 99 | + return findComponentInPackage(matched, component); |
| 100 | + } |
| 101 | + // 未匹配到关键字,依次尝试所有包 |
| 102 | + for (const pkgConfig of lazyPackages) { |
| 103 | + const result = await findComponentInPackage(pkgConfig, component); |
| 104 | + if (result) return result; |
| 105 | + } |
| 106 | + return null; |
22 | 107 | } |
23 | 108 |
|
24 | 109 | // 模块里可使用的import |
|
0 commit comments