fix proxy functionality on Windows

This commit is contained in:
Tw93
2025-10-17 18:01:05 +08:00
parent fabebdbd99
commit d12efb5fdf
2 changed files with 66 additions and 21 deletions

66
dist/cli.js vendored
View File

@@ -23,7 +23,7 @@ import sharp from 'sharp';
import * as psl from 'psl'; import * as psl from 'psl';
var name = "pake-cli"; var name = "pake-cli";
var version = "3.4.0"; var version = "3.4.1";
var description = "🤱🏻 Turn any webpage into a desktop app with one command. 🤱🏻 一键打包网页生成轻量桌面应用。"; var description = "🤱🏻 Turn any webpage into a desktop app with one command. 🤱🏻 一键打包网页生成轻量桌面应用。";
var engines = { var engines = {
node: ">=18.0.0" node: ">=18.0.0"
@@ -201,11 +201,13 @@ const IS_MAC = platform$1 === 'darwin';
const IS_WIN = platform$1 === 'win32'; const IS_WIN = platform$1 === 'win32';
const IS_LINUX = platform$1 === 'linux'; const IS_LINUX = platform$1 === 'linux';
async function shellExec(command, timeout = 300000, env, showOutput = false) { async function shellExec(command, timeout = 300000, env) {
try { try {
const { exitCode } = await execa(command, { const { exitCode } = await execa(command, {
cwd: npmDirectory, cwd: npmDirectory,
stdio: showOutput ? 'inherit' : ['inherit', 'pipe', 'inherit'], // Use 'inherit' to show all output directly to user in real-time.
// This ensures linuxdeploy and other tool outputs are visible during builds.
stdio: 'inherit',
shell: true, shell: true,
timeout, timeout,
env: env ? { ...process.env, ...env } : process.env, env: env ? { ...process.env, ...env } : process.env,
@@ -219,15 +221,25 @@ async function shellExec(command, timeout = 300000, env, showOutput = false) {
throw new Error(`Command timed out after ${timeout}ms: "${command}". Try increasing timeout or check network connectivity.`); throw new Error(`Command timed out after ${timeout}ms: "${command}". Try increasing timeout or check network connectivity.`);
} }
let errorMsg = `Error occurred while executing command "${command}". Exit code: ${exitCode}. Details: ${errorMessage}`; let errorMsg = `Error occurred while executing command "${command}". Exit code: ${exitCode}. Details: ${errorMessage}`;
// Provide helpful guidance for common Linux AppImage build failures
// caused by strip tool incompatibility with modern glibc (2.38+)
if (process.platform === 'linux' && if (process.platform === 'linux' &&
(errorMessage.includes('linuxdeploy') || (errorMessage.includes('linuxdeploy') ||
errorMessage.includes('appimage') || errorMessage.includes('appimage') ||
errorMessage.includes('strip'))) { errorMessage.includes('strip'))) {
errorMsg += errorMsg +=
'\n\nLinux AppImage build error. Try one of these solutions:\n' + '\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n' +
' 1. Run with: NO_STRIP=true pake <url> --targets appimage\n' + 'Linux AppImage Build Failed\n' +
' 2. Use DEB format instead: pake <url> --targets deb\n' + '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n' +
' 3. See detailed solutions: https://github.com/tw93/Pake/blob/main/docs/faq.md'; 'Cause: Strip tool incompatibility with glibc 2.38+\n' +
' (affects Debian Trixie, Arch Linux, and other modern distros)\n\n' +
'Quick fix:\n' +
' NO_STRIP=1 pake <url> --targets appimage --debug\n\n' +
'Alternatives:\n' +
' • Use DEB format: pake <url> --targets deb\n' +
' • Update binutils: sudo apt install binutils (or pacman -S binutils)\n' +
' • Detailed guide: https://github.com/tw93/Pake/blob/main/docs/faq.md\n' +
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━';
} }
throw new Error(errorMsg); throw new Error(errorMsg);
} }
@@ -351,7 +363,7 @@ async function installRust() {
const rustInstallScriptForWindows = 'winget install --id Rustlang.Rustup'; const rustInstallScriptForWindows = 'winget install --id Rustlang.Rustup';
const spinner = getSpinner('Downloading Rust...'); const spinner = getSpinner('Downloading Rust...');
try { try {
await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForMac, 300000, undefined, true); await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForMac, 300000, undefined);
spinner.succeed(chalk.green('✔ Rust installed successfully!')); spinner.succeed(chalk.green('✔ Rust installed successfully!'));
ensureRustEnv(); ensureRustEnv();
} }
@@ -448,13 +460,14 @@ async function mergeConfig(url, options, tauriConf) {
await fsExtra.copy(sourcePath, destPath); await fsExtra.copy(sourcePath, destPath);
} }
})); }));
const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, enableDragDrop, multiInstance, } = options; const { width, height, fullscreen, maximize, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, enableDragDrop, multiInstance, startToTray, } = options;
const { platform } = process; const { platform } = process;
const platformHideOnClose = hideOnClose ?? platform === 'darwin'; const platformHideOnClose = hideOnClose ?? platform === 'darwin';
const tauriConfWindowOptions = { const tauriConfWindowOptions = {
width, width,
height, height,
fullscreen, fullscreen,
maximize,
resizable, resizable,
hide_title_bar: hideTitleBar, hide_title_bar: hideTitleBar,
activation_shortcut: activationShortcut, activation_shortcut: activationShortcut,
@@ -466,6 +479,7 @@ async function mergeConfig(url, options, tauriConf) {
title: title || null, title: title || null,
enable_wasm: wasm, enable_wasm: wasm,
enable_drag_drop: enableDragDrop, enable_drag_drop: enableDragDrop,
start_to_tray: startToTray && showSystemTray,
}; };
Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });
tauriConf.productName = name; tauriConf.productName = name;
@@ -774,10 +788,10 @@ class BaseBuilder {
logger.info(`✺ Located in China, using ${packageManager}/rsProxy CN mirror.`); logger.info(`✺ Located in China, using ${packageManager}/rsProxy CN mirror.`);
const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml'); const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
await fsExtra.copy(projectCnConf, projectConf); await fsExtra.copy(projectCnConf, projectConf);
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv, this.options.debug); await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv);
} }
else { else {
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, buildEnv, this.options.debug); await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, buildEnv);
} }
spinner.succeed(chalk.green('Package installed!')); spinner.succeed(chalk.green('Package installed!'));
if (!tauriTargetPathExists) { if (!tauriTargetPathExists) {
@@ -806,7 +820,16 @@ class BaseBuilder {
...this.getBuildEnvironment(), ...this.getBuildEnvironment(),
...(process.env.NO_STRIP && { NO_STRIP: process.env.NO_STRIP }), ...(process.env.NO_STRIP && { NO_STRIP: process.env.NO_STRIP }),
}; };
await shellExec(`cd "${npmDirectory}" && ${this.getBuildCommand(packageManager)}`, this.getBuildTimeout(), buildEnv, this.options.debug); // Warn users about potential AppImage build failures on modern Linux systems.
// The linuxdeploy tool bundled in Tauri uses an older strip tool that doesn't
// recognize the .relr.dyn section introduced in glibc 2.38+.
if (process.platform === 'linux' && this.options.targets === 'appimage') {
if (!buildEnv.NO_STRIP) {
logger.warn('⚠ Building AppImage on Linux may fail due to strip incompatibility with glibc 2.38+');
logger.warn('⚠ If build fails, retry with: NO_STRIP=1 pake <url> --targets appimage');
}
}
await shellExec(`cd "${npmDirectory}" && ${this.getBuildCommand(packageManager)}`, this.getBuildTimeout(), buildEnv);
// Copy app // Copy app
const fileName = this.getFileName(); const fileName = this.getFileName();
const fileType = this.getFileType(target); const fileType = this.getFileType(target);
@@ -865,6 +888,11 @@ class BaseBuilder {
if (target) { if (target) {
fullCommand += ` --target ${target}`; fullCommand += ` --target ${target}`;
} }
// Enable verbose output in debug mode to help diagnose build issues.
// This provides detailed logs from Tauri CLI and bundler tools.
if (this.options.debug) {
fullCommand += ' --verbose';
}
return fullCommand; return fullCommand;
} }
/** /**
@@ -1178,6 +1206,12 @@ class LinuxBuilder extends BaseBuilder {
if (features.length > 0) { if (features.length > 0) {
fullCommand += ` --features ${features.join(',')}`; fullCommand += ` --features ${features.join(',')}`;
} }
// Enable verbose output for AppImage builds when debugging or PAKE_VERBOSE is set.
// AppImage builds often fail with minimal error messages from linuxdeploy,
// so verbose mode helps diagnose issues like strip failures and missing dependencies.
if (this.options.targets === 'appimage' && (this.options.debug || process.env.PAKE_VERBOSE)) {
fullCommand += ' --verbose';
}
return fullCommand; return fullCommand;
} }
getBasePath() { getBasePath() {
@@ -1227,6 +1261,7 @@ const DEFAULT_PAKE_OPTIONS = {
height: 780, height: 780,
width: 1200, width: 1200,
fullscreen: false, fullscreen: false,
maximize: false,
hideTitleBar: false, hideTitleBar: false,
alwaysOnTop: false, alwaysOnTop: false,
appVersion: '1.0.0', appVersion: '1.0.0',
@@ -1249,6 +1284,7 @@ const DEFAULT_PAKE_OPTIONS = {
enableDragDrop: false, enableDragDrop: false,
keepBinary: false, keepBinary: false,
multiInstance: false, multiInstance: false,
startToTray: false,
}; };
async function checkUpdateTips() { async function checkUpdateTips() {
@@ -1731,6 +1767,9 @@ program
.addOption(new Option('--always-on-top', 'Always on the top level') .addOption(new Option('--always-on-top', 'Always on the top level')
.default(DEFAULT_PAKE_OPTIONS.alwaysOnTop) .default(DEFAULT_PAKE_OPTIONS.alwaysOnTop)
.hideHelp()) .hideHelp())
.addOption(new Option('--maximize', 'Start window maximized')
.default(DEFAULT_PAKE_OPTIONS.maximize)
.hideHelp())
.addOption(new Option('--dark-mode', 'Force Mac app to use dark mode') .addOption(new Option('--dark-mode', 'Force Mac app to use dark mode')
.default(DEFAULT_PAKE_OPTIONS.darkMode) .default(DEFAULT_PAKE_OPTIONS.darkMode)
.hideHelp()) .hideHelp())
@@ -1774,6 +1813,9 @@ program
.addOption(new Option('--multi-instance', 'Allow multiple app instances') .addOption(new Option('--multi-instance', 'Allow multiple app instances')
.default(DEFAULT_PAKE_OPTIONS.multiInstance) .default(DEFAULT_PAKE_OPTIONS.multiInstance)
.hideHelp()) .hideHelp())
.addOption(new Option('--start-to-tray', 'Start app minimized to tray')
.default(DEFAULT_PAKE_OPTIONS.startToTray)
.hideHelp())
.addOption(new Option('--installer-language <string>', 'Installer language') .addOption(new Option('--installer-language <string>', 'Installer language')
.default(DEFAULT_PAKE_OPTIONS.installerLanguage) .default(DEFAULT_PAKE_OPTIONS.installerLanguage)
.hideHelp()) .hideHelp())

View File

@@ -43,6 +43,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
.user_agent(user_agent) .user_agent(user_agent)
.resizable(window_config.resizable) .resizable(window_config.resizable)
.fullscreen(window_config.fullscreen) .fullscreen(window_config.fullscreen)
.maximized(window_config.maximize)
.inner_size(window_config.width, window_config.height) .inner_size(window_config.width, window_config.height)
.always_on_top(window_config.always_on_top) .always_on_top(window_config.always_on_top)
.incognito(window_config.incognito); .incognito(window_config.incognito);
@@ -65,14 +66,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
.additional_browser_args("--enable-unsafe-webgpu"); .additional_browser_args("--enable-unsafe-webgpu");
} }
if !config.proxy_url.is_empty() { // Platform-specific configuration must be set before proxy on Windows/Linux
if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
window_builder = window_builder.proxy_url(proxy_url);
#[cfg(debug_assertions)]
println!("Proxy configured: {}", config.proxy_url);
}
}
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let title_bar_style = if window_config.hide_title_bar { let title_bar_style = if window_config.hide_title_bar {
@@ -87,7 +81,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
} }
} }
// Windows and Linux share the same configuration // Windows and Linux: set data_directory before proxy_url
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
{ {
window_builder = window_builder window_builder = window_builder
@@ -96,5 +90,14 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
.theme(None); .theme(None);
} }
// Set proxy after platform-specific configs (required for Windows/Linux)
if !config.proxy_url.is_empty() {
if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
window_builder = window_builder.proxy_url(proxy_url);
#[cfg(debug_assertions)]
println!("Proxy configured: {}", config.proxy_url);
}
}
window_builder.build().expect("Failed to build window") window_builder.build().expect("Failed to build window")
} }