From 3c12f30b804694e4b5e88511de86d819a8ca58cc Mon Sep 17 00:00:00 2001 From: tangkai <1944876319@qq.com> Date: Thu, 16 Jul 2026 16:41:23 +0800 Subject: [PATCH 1/3] adjust web-mobile preview click callback --- .../web-mobile/src/view/build-config-host.ts | 40 ++++++++++++++++++- .../web-mobile/src/view/build-config.tsx | 13 +++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts b/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts index a90d17a50..862dc05a2 100644 --- a/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts +++ b/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts @@ -1,5 +1,6 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; +import { exec } from 'node:child_process'; type Bundle = Record; @@ -116,6 +117,37 @@ function registerBuildOutput(rawPath: string, outputName: string): void { middleware?.registerBuildPath?.('web-mobile', outputName, rawPath); } +function openBrowser(url: string, completedCallback?: () => void): void { + let command: string | undefined; + switch (process.platform) { + case 'win32': + command = `start ${url}`; + break; + case 'darwin': + command = `open ${url}`; + break; + case 'linux': + command = `xdg-open ${url}`; + break; + default: + completedCallback?.(); + return; + } + + const processWithGlobalOpenUrl = process as typeof process & { addGlobalOpenUrl?: (targetUrl: string) => void }; + if (processWithGlobalOpenUrl.addGlobalOpenUrl) { + processWithGlobalOpenUrl.addGlobalOpenUrl(url); + completedCallback?.(); + return; + } + + exec(command, () => completedCallback?.()); +} + +function openUrlAsync(url: string): Promise { + return new Promise((resolve) => openBrowser(url, resolve)); +} + async function createQRCodeSrc(url: string): Promise { if (!url) { return ''; @@ -143,7 +175,7 @@ async function getPreviewInfo(request: PreviewRequest = {}): Promise getPreviewInfo(request)); + context.registerMethod('openPreviewUrl', async (url: string) => { + if (!url) { + return; + } + await openUrlAsync(url); + }); } diff --git a/src/core/builder/platforms/web-mobile/src/view/build-config.tsx b/src/core/builder/platforms/web-mobile/src/view/build-config.tsx index 5d71b7f02..12cd685b4 100644 --- a/src/core/builder/platforms/web-mobile/src/view/build-config.tsx +++ b/src/core/builder/platforms/web-mobile/src/view/build-config.tsx @@ -83,6 +83,10 @@ export default function WebMobileBuildView({ value, onChange, bridge, commonValu const t = (key: string) => translate(bundle, key); const previewRequest = useMemo(() => ({ buildPath, outputName, useWebGPU }), [buildPath, outputName, useWebGPU]); + const openPreviewUrl = (url: string) => { + bridge?.invoke('openPreviewUrl', url).catch(() => {}); + }; + useEffect(() => { if (!bridge) { return; @@ -172,7 +176,14 @@ export default function WebMobileBuildView({ value, onChange, bridge, commonValu
{previewInfo.previewUrl ? ( - + { + event.preventDefault(); + openPreviewUrl(previewInfo.previewUrl); + }} + > {previewInfo.previewUrl} ) : ( From b64705cb9d80e899896bf7d0dd3d1c851a98cb9f Mon Sep 17 00:00:00 2001 From: tangkai <1944876319@qq.com> Date: Thu, 16 Jul 2026 18:24:22 +0800 Subject: [PATCH 2/3] adjust pink.builder.getPreviewUrl to fetch preview url --- src/core/builder/platforms/types/pink.d.ts | 7 ++ .../web-mobile/scripts/build-view.js | 2 +- .../web-mobile/src/view/build-config-host.ts | 85 ++----------------- .../web-mobile/src/view/build-config.tsx | 4 +- 4 files changed, 16 insertions(+), 82 deletions(-) diff --git a/src/core/builder/platforms/types/pink.d.ts b/src/core/builder/platforms/types/pink.d.ts index 582a3156b..e8c3c8495 100644 --- a/src/core/builder/platforms/types/pink.d.ts +++ b/src/core/builder/platforms/types/pink.d.ts @@ -1473,4 +1473,11 @@ declare module 'pink' { ): import('vscode').WebviewPanel; } + export namespace builder { + /** + * Gets the preview URL for a built web platform. + */ + export function getPreviewUrl(buildPath: string, platform: string): Thenable; + } + } diff --git a/src/core/builder/platforms/web-mobile/scripts/build-view.js b/src/core/builder/platforms/web-mobile/scripts/build-view.js index f3ebfdc8b..397d2a274 100644 --- a/src/core/builder/platforms/web-mobile/scripts/build-view.js +++ b/src/core/builder/platforms/web-mobile/scripts/build-view.js @@ -29,7 +29,7 @@ const hostOptions = { format: 'cjs', platform: 'node', target: 'node18', - external: ['vscode'], + external: ['vscode', 'pink'], logLevel: 'info', }; diff --git a/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts b/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts index 862dc05a2..b47aaf503 100644 --- a/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts +++ b/src/core/builder/platforms/web-mobile/src/view/build-config-host.ts @@ -1,6 +1,6 @@ -import * as fs from 'node:fs'; +import * as pink from 'pink'; +import * as vscode from 'vscode'; import * as path from 'node:path'; -import { exec } from 'node:child_process'; type Bundle = Record; @@ -73,16 +73,6 @@ function substitute(text: string, sub?: Record): string { return text.replace(/%?\{(\w+)\}/g, (match, key: string) => (key in sub ? String(sub[key]) : match)); } -async function getActiveProject(): Promise { - try { - const vscode = require('vscode'); - const project = await vscode?.commands.executeCommand('pink.workspace.getActiveProject'); - return project?.path || ''; - } catch { - return ''; - } -} - function runtimeRequire(request: string): T | undefined { try { return module.require(request) as T; @@ -91,63 +81,6 @@ function runtimeRequire(request: string): T | undefined { } } -function resolveBuildPath(buildPath: string, projectPath: string): string { - if (!buildPath || buildPath === 'project://build') { - return path.join(projectPath, 'build'); - } - if (buildPath.startsWith('project://')) { - return path.join(projectPath, buildPath.replace(/^project:\/\//, '')); - } - return buildPath; -} - -function getServerUrl(): string { - const server = runtimeRequire<{ serverService?: { url?: string } }>(path.join(__dirname, '../../../../../../server/server')); - const url = server?.serverService?.url || ''; - return url && !url.includes('未启动') ? url : 'http://localhost:9527'; -} - -function registerBuildOutput(rawPath: string, outputName: string): void { - if (!fs.existsSync(rawPath)) { - return; - } - const middleware = runtimeRequire<{ registerBuildPath?: (platform: string, name: string, dest: string) => void }>( - path.join(__dirname, '../../../../build.middleware'), - ); - middleware?.registerBuildPath?.('web-mobile', outputName, rawPath); -} - -function openBrowser(url: string, completedCallback?: () => void): void { - let command: string | undefined; - switch (process.platform) { - case 'win32': - command = `start ${url}`; - break; - case 'darwin': - command = `open ${url}`; - break; - case 'linux': - command = `xdg-open ${url}`; - break; - default: - completedCallback?.(); - return; - } - - const processWithGlobalOpenUrl = process as typeof process & { addGlobalOpenUrl?: (targetUrl: string) => void }; - if (processWithGlobalOpenUrl.addGlobalOpenUrl) { - processWithGlobalOpenUrl.addGlobalOpenUrl(url); - completedCallback?.(); - return; - } - - exec(command, () => completedCallback?.()); -} - -function openUrlAsync(url: string): Promise { - return new Promise((resolve) => openBrowser(url, resolve)); -} - async function createQRCodeSrc(url: string): Promise { if (!url) { return ''; @@ -169,15 +102,10 @@ async function createQRCodeSrc(url: string): Promise { } async function getPreviewInfo(request: PreviewRequest = {}): Promise { - const projectPath = await getActiveProject(); const buildPath = request.buildPath || 'project://build'; const outputName = request.outputName || 'web-mobile'; - const buildRoot = resolveBuildPath(buildPath, projectPath); - const rawPath = path.join(buildRoot, outputName); - const serverUrl = getServerUrl(); - const previewUrl = serverUrl ? `${serverUrl}/build/web-mobile/${outputName}/index.html` : ''; - registerBuildOutput(rawPath, outputName); - + const platform = 'web-mobile'; + const previewUrl = await pink.builder.getPreviewUrl(path.join(buildPath, outputName), platform) || ''; const webGPUTips = request.useWebGPU && previewUrl && !previewUrl.startsWith('https') ? lookup(loadBundle(), 'tips.webGPUServer') || '' : ''; @@ -198,9 +126,8 @@ export function activate(context: HostContext): void { }); context.registerMethod('getPreviewInfo', (request: PreviewRequest) => getPreviewInfo(request)); context.registerMethod('openPreviewUrl', async (url: string) => { - if (!url) { - return; + if (url) { + await vscode.env.openExternal(vscode.Uri.parse(url)); } - await openUrlAsync(url); }); } diff --git a/src/core/builder/platforms/web-mobile/src/view/build-config.tsx b/src/core/builder/platforms/web-mobile/src/view/build-config.tsx index 12cd685b4..754dcd675 100644 --- a/src/core/builder/platforms/web-mobile/src/view/build-config.tsx +++ b/src/core/builder/platforms/web-mobile/src/view/build-config.tsx @@ -79,7 +79,7 @@ export default function WebMobileBuildView({ value, onChange, bridge, commonValu const useWebGPU = boolValue(value.useWebGPU); const outputName = stringValue(commonValue?.outputName) || 'web-mobile'; const buildPath = stringValue(commonValue?.buildPath) || 'project://build'; - + console.log('buildPath', buildPath, outputName, useWebGPU); const t = (key: string) => translate(bundle, key); const previewRequest = useMemo(() => ({ buildPath, outputName, useWebGPU }), [buildPath, outputName, useWebGPU]); @@ -179,7 +179,7 @@ export default function WebMobileBuildView({ value, onChange, bridge, commonValu { + onClick={(event: { preventDefault(): void }) => { event.preventDefault(); openPreviewUrl(previewInfo.previewUrl); }} From 65b053c2c231cf7dc74f85bec2b738ddad64c8b9 Mon Sep 17 00:00:00 2001 From: tangkai <1944876319@qq.com> Date: Thu, 16 Jul 2026 18:26:11 +0800 Subject: [PATCH 3/3] delete log --- src/core/builder/platforms/web-mobile/src/view/build-config.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/builder/platforms/web-mobile/src/view/build-config.tsx b/src/core/builder/platforms/web-mobile/src/view/build-config.tsx index 754dcd675..c4bfc3849 100644 --- a/src/core/builder/platforms/web-mobile/src/view/build-config.tsx +++ b/src/core/builder/platforms/web-mobile/src/view/build-config.tsx @@ -79,7 +79,6 @@ export default function WebMobileBuildView({ value, onChange, bridge, commonValu const useWebGPU = boolValue(value.useWebGPU); const outputName = stringValue(commonValue?.outputName) || 'web-mobile'; const buildPath = stringValue(commonValue?.buildPath) || 'project://build'; - console.log('buildPath', buildPath, outputName, useWebGPU); const t = (key: string) => translate(bundle, key); const previewRequest = useMemo(() => ({ buildPath, outputName, useWebGPU }), [buildPath, outputName, useWebGPU]);