From f2a5a17f95bd8bd8858aafbc7f52646a085e48d4 Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Thu, 25 Dec 2025 13:42:49 +0800 Subject: [PATCH] ui-next: add hydroPlugins to dynamically load route plugins --- packages/hydrooj/src/interface.ts | 2 +- packages/ui-next/index.ts | 33 ++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index f2bf5bbbf..56e94538e 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -622,7 +622,7 @@ export interface ProblemSearchOptions { export type ProblemSearch = (domainId: string, q: string, options?: ProblemSearchOptions) => Promise; -export type UIInjectableFields = 'ProblemAdd' | 'Notification' | 'Nav' | 'UserDropdown' | 'DomainManage' | 'ControlPanel'; +export type UIInjectableFields = 'ProblemAdd' | 'Notification' | 'Nav' | 'UserDropdown' | 'DomainManage' | 'ControlPanel' | 'Route'; export interface UI { nodes: Record; getNodes: typeof import('./lib/ui').getNodes; diff --git a/packages/ui-next/index.ts b/packages/ui-next/index.ts index 30acceb3c..e2b16e870 100644 --- a/packages/ui-next/index.ts +++ b/packages/ui-next/index.ts @@ -1,14 +1,37 @@ import fs from 'fs'; import path from 'path'; -import importMetaUrlPlugin from '@codingame/esbuild-import-meta-url-plugin'; -import react from '@vitejs/plugin-react-swc'; +import importMetaUrlPlugin from '@chialab/esbuild-plugin-meta-url'; +import react from '@vitejs/plugin-react'; import c2k from 'koa2-connect/ts'; -import { createServer } from 'vite'; +import { createServer, type Plugin } from 'vite'; import { } from '@hydrooj/framework'; -import { Context } from 'hydrooj'; +import { Context, getNodes } from 'hydrooj'; const INJECT_MARKER = ''; +function hydroPlugins(): Plugin { + const virtualModuleId = 'virtual:hydro-plugins'; + const resolvedVirtualModuleId = `\0${virtualModuleId}`; + + return { + name: 'hydro-plugins', + resolveId(id) { + if (id === virtualModuleId) { + return resolvedVirtualModuleId; + } + }, + load(id) { + if (id === resolvedVirtualModuleId) { + const plugins = getNodes('Route'); + if (!plugins) return 'export default [];'; + const imports = plugins.map((p, i) => `import plugin${i} from '${p.args.entry}';`).join('\n'); + const exports = `export default [${plugins.map((p, i) => `plugin${i}`).join(', ')}];`; + return `${imports}\n${exports}`; + } + }, + }; +} + export async function apply(ctx: Context) { if (process.env.HYDRO_CLI) return; const vite = await createServer({ @@ -26,7 +49,7 @@ export async function apply(ctx: Context) { appType: 'custom', root: __dirname, base: '/', - plugins: [react()], + plugins: [react(), hydroPlugins()], optimizeDeps: { esbuildOptions: { plugins: [