Merge pull request #1073 from tw93/claude/investigate-issue-1071-011CV5PH46UcnFtKfbfJ6Cot

Fix Windows installation timeout with smart retry mechanism (#1071)
This commit is contained in:
Tw93
2025-11-13 14:34:37 +08:00
committed by GitHub
4 changed files with 200 additions and 37 deletions

View File

@@ -34,7 +34,8 @@ export default abstract class BaseBuilder {
}
private getInstallTimeout(): number {
return process.platform === 'win32' ? 600000 : 300000;
// Windows needs more time due to native compilation and antivirus scanning
return process.platform === 'win32' ? 900000 : 600000;
}
private getBuildTimeout(): number {
@@ -100,38 +101,74 @@ export default abstract class BaseBuilder {
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) {
// Show helpful message for first-time users
if (!tauriTargetPathExists) {
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,
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)...',
);
}
spinner.succeed(chalk.green('Package installed!'));
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: any) {
// 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;
}
}
if (!tauriTargetPathExists) {
logger.warn(
'✼ The first packaging may be slow, please be patient and wait, it will be faster afterwards.',

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.');
}

48
docs/faq.md vendored
View File

@@ -6,6 +6,54 @@ Common issues and solutions when using Pake.
## Build Issues
### Windows: Installation Timeout During First Build
**Problem:**
When building for the first time on Windows, you may encounter:
```txt
Error: Command timed out after 900000ms: "cd ... && pnpm install"
```
**Why This Happens:**
First-time installation on Windows can be slow due to:
- Native module compilation (requires Visual Studio Build Tools)
- Large dependency downloads (Tauri, Rust toolchain)
- Windows Defender real-time scanning
- Network connectivity issues
**Solution 1: Automatic Retry (Built-in)**
Pake CLI now automatically retries with CN mirror if the initial installation times out. Simply wait for the retry to complete.
**Solution 2: Manual Installation**
If automatic retry fails, manually install dependencies:
```bash
# Navigate to pake-cli installation directory
cd %LOCALAPPDATA%\pnpm\global\5\.pnpm\pake-cli@VERSION\node_modules\pake-cli
# Install with CN mirror
pnpm install --registry=https://registry.npmmirror.com
# Then retry your build
pake https://github.com --name GitHub
```
**Solution 3: Improve Network Speed**
- Use a stable network connection
- Temporarily disable antivirus software during installation
- Use a VPN or proxy if needed
**Expected Time:**
- First installation: 10-15 minutes on Windows
- Subsequent builds: Much faster (dependencies cached)
---
### Linux: AppImage Build Fails with "failed to run linuxdeploy"
**Problem:**

48
docs/faq_CN.md vendored
View File

@@ -6,6 +6,54 @@
## 构建问题
### Windows首次构建时安装超时
**问题描述:**
在 Windows 上首次构建时,可能遇到:
```txt
Error: Command timed out after 900000ms: "cd ... && pnpm install"
```
**原因分析:**
Windows 首次安装可能较慢,原因包括:
- 本地模块编译(需要 Visual Studio Build Tools
- 大量依赖下载Tauri、Rust 工具链)
- Windows Defender 实时扫描
- 网络连接问题
**解决方案 1自动重试内置**
Pake CLI 现在会在初次安装超时后自动使用国内镜像重试。只需等待重试完成即可。
**解决方案 2手动安装依赖**
如果自动重试失败,可手动安装依赖:
```bash
# 进入 pake-cli 安装目录
cd %LOCALAPPDATA%\pnpm\global\5\.pnpm\pake-cli@版本号\node_modules\pake-cli
# 使用国内镜像安装
pnpm install --registry=https://registry.npmmirror.com
# 然后重新构建
pake https://github.com --name GitHub
```
**解决方案 3改善网络环境**
- 使用稳定的网络连接
- 安装过程中临时关闭杀毒软件
- 必要时使用 VPN 或代理
**预期时间:**
- 首次安装Windows 上需要 10-15 分钟
- 后续构建:依赖已缓存,速度会快很多
---
### LinuxAppImage 构建失败,提示 "failed to run linuxdeploy"
**问题描述:**