Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/core/builder/platforms/types/pink.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const hostOptions = {
format: 'cjs',
platform: 'node',
target: 'node18',
external: ['vscode'],
external: ['vscode', 'pink'],
logLevel: 'info',
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as fs from 'node:fs';
import * as pink from 'pink';
import * as vscode from 'vscode';
import * as path from 'node:path';

type Bundle = Record<string, unknown>;
Expand Down Expand Up @@ -72,16 +73,6 @@ function substitute(text: string, sub?: Record<string, unknown>): string {
return text.replace(/%?\{(\w+)\}/g, (match, key: string) => (key in sub ? String(sub[key]) : match));
}

async function getActiveProject(): Promise<string> {
try {
const vscode = require('vscode');
const project = await vscode?.commands.executeCommand('pink.workspace.getActiveProject');
return project?.path || '';
} catch {
return '';
}
}

function runtimeRequire<T = any>(request: string): T | undefined {
try {
return module.require(request) as T;
Expand All @@ -90,32 +81,6 @@ function runtimeRequire<T = any>(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);
}

async function createQRCodeSrc(url: string): Promise<string> {
if (!url) {
return '';
Expand All @@ -137,15 +102,10 @@ async function createQRCodeSrc(url: string): Promise<string> {
}

async function getPreviewInfo(request: PreviewRequest = {}): Promise<PreviewInfo> {
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}/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') || ''
: '';
Expand All @@ -165,4 +125,9 @@ export function activate(context: HostContext): void {
return text === undefined ? key : substitute(text, sub);
});
context.registerMethod('getPreviewInfo', (request: PreviewRequest) => getPreviewInfo(request));
context.registerMethod('openPreviewUrl', async (url: string) => {
if (url) {
await vscode.env.openExternal(vscode.Uri.parse(url));
}
});
}
14 changes: 12 additions & 2 deletions src/core/builder/platforms/web-mobile/src/view/build-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ 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';

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;
Expand Down Expand Up @@ -172,7 +175,14 @@ export default function WebMobileBuildView({ value, onChange, bridge, commonValu
<TypedField label={t('options.preview_url')}>
<div style={INLINE}>
{previewInfo.previewUrl ? (
<a href={previewInfo.previewUrl} style={LINK}>
<a
href={previewInfo.previewUrl}
style={LINK}
onClick={(event: { preventDefault(): void }) => {
event.preventDefault();
openPreviewUrl(previewInfo.previewUrl);
}}
>
{previewInfo.previewUrl}
</a>
) : (
Expand Down
Loading