From fa4b8910c8b59bfa3eb0cde5318d9017c06ee6dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Sun, 1 Mar 2026 20:27:57 +0800 Subject: [PATCH] chore: support code-inspector for vinext (#32788) --- web/vite.config.ts | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/web/vite.config.ts b/web/vite.config.ts index 676173e3de..1fdef49d0c 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,15 +1,78 @@ import type { Plugin } from 'vite' +import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import react from '@vitejs/plugin-react' +import { codeInspectorPlugin } from 'code-inspector-plugin' import vinext from 'vinext' import { defineConfig } from 'vite' import tsconfigPaths from 'vite-tsconfig-paths' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const isCI = !!process.env.CI +const inspectorPort = 5678 +const inspectorInjectTarget = path.resolve(__dirname, 'app/components/browser-initializer.tsx') +const inspectorRuntimeFile = path.resolve( + __dirname, + `node_modules/code-inspector-plugin/dist/append-code-${inspectorPort}.js`, +) + +const getInspectorRuntimeSnippet = (): string => { + if (!fs.existsSync(inspectorRuntimeFile)) + return '' + + const raw = fs.readFileSync(inspectorRuntimeFile, 'utf-8') + // Remove the helper module default export from append file to avoid duplicate default exports. + return raw.replace( + /\s*export default function CodeInspectorEmptyElement\(\)\s*\{[\s\S]*$/, + '', + ) +} + +const normalizeInspectorModuleId = (id: string): string => { + const withoutQuery = id.split('?', 1)[0] + + // Vite/vinext may pass absolute fs modules as "/@fs/". + if (withoutQuery.startsWith('/@fs/')) + return withoutQuery.slice('/@fs'.length) + + return withoutQuery +} + +const createCodeInspectorPlugin = (): Plugin => { + return codeInspectorPlugin({ + bundler: 'vite', + port: inspectorPort, + injectTo: inspectorInjectTarget, + exclude: [/^(?!.*\.(?:js|ts|mjs|mts|jsx|tsx|vue|svelte|html)(?:$|\?)).*/], + }) as Plugin +} + +const createForceInspectorClientInjectionPlugin = (): Plugin => { + const clientSnippet = getInspectorRuntimeSnippet() + + return { + name: 'vinext-force-code-inspector-client', + apply: 'serve', + enforce: 'pre', + transform(code, id) { + if (!clientSnippet) + return null + + const cleanId = normalizeInspectorModuleId(id) + if (cleanId !== inspectorInjectTarget) + return null + if (code.includes('code-inspector-component')) + return null + + return `${clientSnippet}\n${code}` + }, + } +} export default defineConfig(({ mode }) => { + const isDev = mode === 'development' + return { plugins: mode === 'test' ? [ @@ -26,6 +89,12 @@ export default defineConfig(({ mode }) => { } as Plugin, ] : [ + ...(isDev + ? [ + createCodeInspectorPlugin(), + createForceInspectorClientInjectionPlugin(), + ] + : []), vinext(), ], resolve: {