Files
MyGoNavi/tools/wails-fast-dev.mjs
Syngnat a5be4cc3ae ️ perf(dev): 优化 Wails 开发启动与 CI 构建耗时
- 新增 Wails 快速开发启动脚本,跳过非必要构建与绑定生成
- 优化前端依赖安装状态判断,减少重复 npm install
- 固定 CI Wails CLI 版本并增加 node_modules 缓存
- 更新开发文档中的快速启动说明
2026-05-16 11:02:43 +08:00

116 lines
3.7 KiB
JavaScript

#!/usr/bin/env node
import { spawn, spawnSync } from 'node:child_process';
import { existsSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.resolve(scriptDir, '..');
const frontendDir = path.join(projectRoot, 'frontend');
const wailsConfigPath = path.join(projectRoot, 'wails.json');
const nodeCommand = process.execPath;
const wailsCommand = process.platform === 'win32' ? 'wails.exe' : 'wails';
const usage = `Usage:
node tools/wails-fast-dev.mjs [--refresh-bindings] [--no-install] [--dry-run] [wails dev flags...]
Fast path:
- skips npm install when frontend dependencies are unchanged
- runs wails dev with -m -s -nosyncgomod -skipembedcreate
- skips Wails binding generation unless --refresh-bindings is passed
Use --refresh-bindings after changing exported Go method signatures.`;
const rawArgs = process.argv.slice(2);
if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
console.log(usage);
process.exit(0);
}
const readWailsConfig = () => {
try {
return JSON.parse(readFileSync(wailsConfigPath, 'utf8'));
} catch (error) {
console.error(`Failed to read wails.json: ${error.message}`);
process.exit(1);
}
};
const runFrontendInstall = () => {
const result = spawnSync(nodeCommand, ['scripts/wails-frontend-install.mjs'], {
cwd: frontendDir,
env: process.env,
stdio: 'inherit',
});
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
};
const hasFlag = (args, names) =>
args.some((arg) => names.some((name) => arg === name || arg.startsWith(`${name}=`)));
const wailsConfig = readWailsConfig();
const dryRun = rawArgs.includes('--dry-run');
const refreshBindings = rawArgs.includes('--refresh-bindings') || process.env.GONAVI_REFRESH_WAILS_BINDINGS === '1';
const skipInstall = rawArgs.includes('--no-install') || process.env.GONAVI_FAST_DEV_SKIP_INSTALL === '1';
const passThroughArgs = rawArgs.filter((arg) => arg !== '--refresh-bindings' && arg !== '--no-install' && arg !== '--dry-run');
const devServerUrl = process.env.GONAVI_FRONTEND_DEV_SERVER_URL || wailsConfig['frontend:dev:serverUrl'] || 'http://localhost:5173';
const wailsjsRoot = path.resolve(projectRoot, wailsConfig.wailsjsdir || './frontend', 'wailsjs');
const skipBindings = !refreshBindings && existsSync(wailsjsRoot);
const fastArgs = ['dev'];
if (!skipInstall && !dryRun) {
runFrontendInstall();
}
if (!hasFlag(passThroughArgs, ['-m'])) {
fastArgs.push('-m');
}
if (!hasFlag(passThroughArgs, ['-s'])) {
fastArgs.push('-s');
}
if (!hasFlag(passThroughArgs, ['-nosyncgomod'])) {
fastArgs.push('-nosyncgomod');
}
if (!hasFlag(passThroughArgs, ['-skipembedcreate'])) {
fastArgs.push('-skipembedcreate');
}
if (skipBindings && !hasFlag(passThroughArgs, ['-skipbindings'])) {
fastArgs.push('-skipbindings');
}
if (!hasFlag(passThroughArgs, ['-frontenddevserverurl'])) {
fastArgs.push('-frontenddevserverurl', devServerUrl);
}
if (!skipBindings && !refreshBindings) {
console.warn('frontend/wailsjs not found; generating Wails bindings this run.');
}
if (dryRun) {
const quoteArg = (arg) => (/\s/.test(arg) ? JSON.stringify(arg) : arg);
console.log(`Would run: ${[wailsCommand, ...fastArgs, ...passThroughArgs].map(quoteArg).join(' ')}`);
process.exit(0);
}
const child = spawn(wailsCommand, [...fastArgs, ...passThroughArgs], {
cwd: projectRoot,
env: process.env,
stdio: 'inherit',
});
child.on('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
return;
}
process.exit(code ?? 0);
});
child.on('error', (error) => {
console.error(`Failed to start Wails CLI: ${error.message}`);
process.exit(1);
});