From 5c920cbd43cffa4595abad331e997dd0fada4bbb Mon Sep 17 00:00:00 2001 From: Tw93 Date: Sat, 23 Aug 2025 18:26:42 +0800 Subject: [PATCH] :sparkles: Parameters support web wasm scenarios --- bin/README.md | 13 +++++++++++++ bin/README_CN.md | 13 +++++++++++++ bin/cli.ts | 16 ++++++++-------- bin/defaults.ts | 1 + bin/helpers/merge.ts | 12 ++++++++++++ bin/types.ts | 3 +++ dist/cli.js | 25 ++++++++++++++++++------- package-lock.json | 4 ++-- src-tauri/src/app/config.rs | 1 + src-tauri/src/app/window.rs | 7 +++++++ src-tauri/tauri.conf.json | 3 +++ 11 files changed, 81 insertions(+), 17 deletions(-) diff --git a/bin/README.md b/bin/README.md index 13e5a25..73eb219 100644 --- a/bin/README.md +++ b/bin/README.md @@ -271,6 +271,19 @@ Launch the application in incognito/private browsing mode. Default is `false`. W --incognito ``` +#### [wasm] + +Enable WebAssembly support with cross-origin isolation headers. Required for Flutter Web applications and other web applications that use WebAssembly modules like `sqlite3.wasm`, `canvaskit.wasm`. Default is `false`. + +This option adds necessary HTTP headers (`Cross-Origin-Opener-Policy: same-origin` and `Cross-Origin-Embedder-Policy: require-corp`) and browser flags to enable SharedArrayBuffer and WebAssembly features. + +```shell +--wasm + +# Example: Package a Flutter Web app with WASM support +pake https://flutter.dev --name FlutterApp --wasm +``` + #### [installer-language] Set the Windows Installer language. Options include `zh-CN`, `ja-JP`, More at [Tauri Document](https://tauri.app/distribute/windows-installer/#internationalization). Default is `en-US`. diff --git a/bin/README_CN.md b/bin/README_CN.md index 5507cf9..3309152 100644 --- a/bin/README_CN.md +++ b/bin/README_CN.md @@ -259,6 +259,19 @@ pake [url] [options] --incognito ``` +#### [wasm] + +启用 WebAssembly 支持,添加跨域隔离头部,适用于 Flutter Web 应用以及其他使用 WebAssembly 模块(如 `sqlite3.wasm`、`canvaskit.wasm`)的 Web 应用,默认为 `false`。 + +此选项会添加必要的 HTTP 头部(`Cross-Origin-Opener-Policy: same-origin` 和 `Cross-Origin-Embedder-Policy: require-corp`)以及浏览器标志,以启用 SharedArrayBuffer 和 WebAssembly 功能。 + +```shell +--wasm + +# 示例:打包支持 WASM 的 Flutter Web 应用 +pake https://flutter.dev --name FlutterApp --wasm +``` + #### [title] 设置窗口标题栏文本。如果未指定,窗口标题将为空。 diff --git a/bin/cli.ts b/bin/cli.ts index d71a5c0..25cd1d2 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -135,6 +135,11 @@ program .default(DEFAULT.incognito) .hideHelp(), ) + .addOption( + new Option('--wasm', 'Enable WebAssembly support (Flutter Web, etc.)') + .default(DEFAULT.wasm) + .hideHelp(), + ) .addOption( new Option('--installer-language ', 'Installer language') .default(DEFAULT.installerLanguage) @@ -145,15 +150,10 @@ program await checkUpdateTips(); if (!url) { - program.outputHelp((str) => { - return str - .split('\n') - .filter( - (line) => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line), - ) - .join('\n'); + program.help({ + error: false }); - process.exit(0); + return; } log.setDefaultLevel('info'); diff --git a/bin/defaults.ts b/bin/defaults.ts index e85dc28..dd38870 100644 --- a/bin/defaults.ts +++ b/bin/defaults.ts @@ -24,6 +24,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = { installerLanguage: 'en-US', hideOnClose: true, incognito: false, + wasm: false, }; // Just for cli development diff --git a/bin/helpers/merge.ts b/bin/helpers/merge.ts index 8cec845..5201a56 100644 --- a/bin/helpers/merge.ts +++ b/bin/helpers/merge.ts @@ -60,6 +60,7 @@ export async function mergeConfig( hideOnClose, incognito, title, + wasm, } = options; const { platform } = process; @@ -78,6 +79,7 @@ export async function mergeConfig( hide_on_close: hideOnClose, incognito: incognito, title: title || null, + enable_wasm: wasm, }; Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); @@ -312,6 +314,16 @@ StartupNotify=true } tauriConf.pake.proxy_url = proxyUrl || ''; + // Configure WASM support with required HTTP headers + if (wasm) { + tauriConf.app.security = { + headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp' + } + }; + } + // Save config file. const platformConfigPaths: PlatformMap = { win32: 'tauri.windows.conf.json', diff --git a/bin/types.ts b/bin/types.ts index ee739b4..1237e16 100644 --- a/bin/types.ts +++ b/bin/types.ts @@ -78,6 +78,9 @@ export interface PakeCliOptions { // Launch app in incognito/private mode, default false incognito: boolean; + + // Enable WebAssembly support (Flutter Web, etc.), default false + wasm: boolean; } export interface PakeAppOptions extends PakeCliOptions { diff --git a/dist/cli.js b/dist/cli.js index 55aba78..67a5b9a 100755 --- a/dist/cli.js +++ b/dist/cli.js @@ -344,7 +344,7 @@ async function mergeConfig(url, options, tauriConf) { 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, } = options; + 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, } = options; const { platform } = process; // Set Windows parameters. const tauriConfWindowOptions = { @@ -360,6 +360,7 @@ async function mergeConfig(url, options, tauriConf) { hide_on_close: hideOnClose, incognito: incognito, title: title || null, + enable_wasm: wasm, }; Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); tauriConf.productName = name; @@ -553,6 +554,15 @@ StartupNotify=true await fsExtra.writeFile(injectFilePath, ''); } tauriConf.pake.proxy_url = proxyUrl || ''; + // Configure WASM support with required HTTP headers + if (wasm) { + tauriConf.app.security = { + headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp' + } + }; + } // Save config file. const platformConfigPaths = { win32: 'tauri.windows.conf.json', @@ -1030,6 +1040,7 @@ const DEFAULT_PAKE_OPTIONS = { installerLanguage: 'en-US', hideOnClose: true, incognito: false, + wasm: false, }; async function checkUpdateTips() { @@ -1481,6 +1492,9 @@ program .addOption(new Option('--incognito', 'Launch app in incognito/private mode') .default(DEFAULT_PAKE_OPTIONS.incognito) .hideHelp()) + .addOption(new Option('--wasm', 'Enable WebAssembly support (Flutter Web, etc.)') + .default(DEFAULT_PAKE_OPTIONS.wasm) + .hideHelp()) .addOption(new Option('--installer-language ', 'Installer language') .default(DEFAULT_PAKE_OPTIONS.installerLanguage) .hideHelp()) @@ -1488,13 +1502,10 @@ program .action(async (url, options) => { await checkUpdateTips(); if (!url) { - program.outputHelp((str) => { - return str - .split('\n') - .filter((line) => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line)) - .join('\n'); + program.help({ + error: false }); - process.exit(0); + return; } log.setDefaultLevel('info'); if (options.debug) { diff --git a/package-lock.json b/package-lock.json index bdf9aa8..ea7f8a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pake-cli", - "version": "3.2.15", + "version": "3.2.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pake-cli", - "version": "3.2.15", + "version": "3.2.16", "license": "MIT", "dependencies": { "@tauri-apps/api": "^2.8.0", diff --git a/src-tauri/src/app/config.rs b/src-tauri/src/app/config.rs index 51ef52f..cc3d74c 100644 --- a/src-tauri/src/app/config.rs +++ b/src-tauri/src/app/config.rs @@ -16,6 +16,7 @@ pub struct WindowConfig { pub hide_on_close: bool, pub incognito: bool, pub title: Option, + pub enable_wasm: bool, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs index 6958575..2198b4a 100644 --- a/src-tauri/src/app/window.rs +++ b/src-tauri/src/app/window.rs @@ -46,6 +46,13 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) -> .initialization_script(include_str!("../inject/style.js")) .initialization_script(include_str!("../inject/custom.js")); + // Configure WASM support with required headers for SharedArrayBuffer + if window_config.enable_wasm { + window_builder = window_builder + .additional_browser_args("--enable-features=SharedArrayBuffer") + .additional_browser_args("--enable-unsafe-webgpu"); + } + // Configure proxy if specified if !config.proxy_url.is_empty() { if let Ok(proxy_url) = Url::from_str(&config.proxy_url) { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 9fc2033..9a98799 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,6 +8,9 @@ "iconPath": "png/weekly_512.png", "iconAsTemplate": false, "id": "pake-tray" + }, + "security": { + "headers": {} } }, "build": {