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:
83
bin/builders/BaseBuilder.ts
vendored
83
bin/builders/BaseBuilder.ts
vendored
@@ -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
58
dist/cli.js
vendored
@@ -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
48
docs/faq.md
vendored
@@ -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
48
docs/faq_CN.md
vendored
@@ -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 分钟
|
||||
- 后续构建:依赖已缓存,速度会快很多
|
||||
|
||||
---
|
||||
|
||||
### Linux:AppImage 构建失败,提示 "failed to run linuxdeploy"
|
||||
|
||||
**问题描述:**
|
||||
|
||||
Reference in New Issue
Block a user