Fix Windows installation timeout with smart retry mechanism (#1071)

Problem:
- Windows users experiencing 10-minute timeout during first build
- Network detection didn't help users with low latency but slow downloads
- Native compilation and antivirus scanning make Windows builds slower

Solution:
1. Increase timeout: Windows 15min (from 10min), other platforms 10min (from 5min)
2. Smart retry: Auto-retry with CN mirror if first attempt times out
3. Better UX: Show expected time (10-15min for Windows first build)
4. Documentation: Add Windows timeout troubleshooting to FAQ

Technical changes:
- BaseBuilder.ts: Implement try-catch with automatic mirror fallback
- FAQ: Document the issue, causes, and solutions in both EN/CN
- User-friendly messages for first-time setup expectations

Fixes #1071
This commit is contained in:
Claude
2025-11-13 06:30:24 +00:00
parent 6e2c1c22bf
commit 07afdd8eeb
4 changed files with 200 additions and 37 deletions

58
dist/cli.js vendored
View File

@@ -730,7 +730,8 @@ class BaseBuilder {
: undefined;
}
getInstallTimeout() {
return process.platform === 'win32' ? 600000 : 300000;
// Windows needs more time due to native compilation and antivirus scanning
return process.platform === 'win32' ? 900000 : 600000;
}
getBuildTimeout() {
return 900000;
@@ -786,25 +787,54 @@ class BaseBuilder {
const rustProjectDir = path.join(tauriSrcPath, '.cargo');
const projectConf = path.join(rustProjectDir, 'config.toml');
await fsExtra.ensureDir(rustProjectDir);
// 智能检测可用的包管理器
// Detect available package manager
const packageManager = await this.detectPackageManager();
const registryOption = isChina
? ' --registry=https://registry.npmmirror.com'
: '';
// 根据包管理器类型设置依赖冲突解决选项
const registryOption = ' --registry=https://registry.npmmirror.com';
const peerDepsOption = packageManager === 'npm' ? ' --legacy-peer-deps' : '';
const timeout = this.getInstallTimeout();
const buildEnv = this.getBuildEnvironment();
if (isChina) {
logger.info(`✺ Located in China, using ${packageManager}/rsProxy CN mirror.`);
const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
await fsExtra.copy(projectCnConf, projectConf);
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv);
// Show helpful message for first-time users
if (!tauriTargetPathExists) {
logger.info(process.platform === 'win32'
? '✺ First-time setup may take 10-15 minutes on Windows (compiling dependencies)...'
: '✺ First-time setup may take 5-10 minutes (installing dependencies)...');
}
else {
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, buildEnv);
let usedMirror = isChina;
try {
if (isChina) {
logger.info(`✺ Located in China, using ${packageManager}/rsProxy CN mirror.`);
const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
await fsExtra.copy(projectCnConf, projectConf);
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv);
}
else {
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, buildEnv);
}
spinner.succeed(chalk.green('Package installed!'));
}
catch (error) {
// If installation times out and we haven't tried the mirror yet, retry with mirror
if (error.message?.includes('timed out') && !usedMirror) {
spinner.fail(chalk.yellow('Installation timed out, retrying with CN mirror...'));
logger.info('✺ Retrying installation with CN mirror for better speed...');
const retrySpinner = getSpinner('Retrying installation...');
usedMirror = true;
try {
const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
await fsExtra.copy(projectCnConf, projectConf);
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv);
retrySpinner.succeed(chalk.green('Package installed with CN mirror!'));
}
catch (retryError) {
retrySpinner.fail(chalk.red('Installation failed'));
throw retryError;
}
}
else {
spinner.fail(chalk.red('Installation failed'));
throw error;
}
}
spinner.succeed(chalk.green('Package installed!'));
if (!tauriTargetPathExists) {
logger.warn('✼ The first packaging may be slow, please be patient and wait, it will be faster afterwards.');
}