修复桌面壳开发入口地址
桌面壳 dev 模式手动创建主窗口时改用 Tauri devUrl 桌面导航策略允许本机 Vite devUrl 留在 WebView 内 补充桌面壳 devUrl 回归测试和文档记忆
This commit is contained in:
@@ -2772,12 +2772,16 @@ const requiredRustHostSnippets = [
|
||||
'desktop_h5_url_with_host_context(target_url)',
|
||||
'desktop_h5_url_with_host_context(normalized_url)',
|
||||
'desktop_window_config_with_runtime_platform',
|
||||
'apply_desktop_dev_url_to_main_window_config',
|
||||
'DESKTOP_MAIN_WINDOW_LABEL: &str = "main"',
|
||||
'desktop_main_window_config_from_windows',
|
||||
'.find(|window| window.label == DESKTOP_MAIN_WINDOW_LABEL)',
|
||||
'tauri::Error::WindowNotFound',
|
||||
'desktop_main_window_config(app)?',
|
||||
'desktop_main_window_config_uses_labeled_main_window',
|
||||
'desktop_main_window_config_uses_dev_url_in_dev_builds',
|
||||
'config.url = tauri::WebviewUrl::External(dev_url.clone())',
|
||||
'assert_eq!(url.origin().ascii_serialization(), "http://127.0.0.1:3000")',
|
||||
'path.starts_with("index.html?")',
|
||||
'path.contains("clientRuntime=native_app")',
|
||||
'path.contains("clientType=native_app")',
|
||||
@@ -2787,6 +2791,9 @@ const requiredRustHostSnippets = [
|
||||
'path.contains("bridgeVersion=")',
|
||||
'path.contains("hostCapabilities=")',
|
||||
'should_allow_desktop_webview_navigation',
|
||||
'url.host_str() == Some("127.0.0.1")',
|
||||
'url.port_or_known_default() == Some(3000)',
|
||||
'Url::parse("http://127.0.0.1:3000/works/detail?work=PZ-1")',
|
||||
'desktop_external_navigation_url',
|
||||
'open_normalized_desktop_external_url',
|
||||
'open_desktop_external_navigation',
|
||||
|
||||
@@ -32,10 +32,24 @@ fn desktop_main_window_config_from_windows(
|
||||
.ok_or(tauri::Error::WindowNotFound)
|
||||
}
|
||||
|
||||
#[cfg(dev)]
|
||||
fn apply_desktop_dev_url_to_main_window_config(
|
||||
mut config: tauri::utils::config::WindowConfig,
|
||||
dev_url: &tauri::Url,
|
||||
) -> tauri::utils::config::WindowConfig {
|
||||
config.url = tauri::WebviewUrl::External(dev_url.clone());
|
||||
desktop_window_config_with_runtime_platform(config)
|
||||
}
|
||||
|
||||
fn desktop_main_window_config(
|
||||
app: &tauri::App,
|
||||
) -> tauri::Result<tauri::utils::config::WindowConfig> {
|
||||
desktop_main_window_config_from_windows(&app.config().app.windows)
|
||||
let config = desktop_main_window_config_from_windows(&app.config().app.windows)?;
|
||||
#[cfg(dev)]
|
||||
if let Some(dev_url) = app.config().build.dev_url.as_ref() {
|
||||
return Ok(apply_desktop_dev_url_to_main_window_config(config, dev_url));
|
||||
}
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
fn desktop_new_window_external_url(url: &tauri::Url) -> Option<String> {
|
||||
@@ -157,6 +171,39 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(dev)]
|
||||
#[test]
|
||||
fn desktop_main_window_config_uses_dev_url_in_dev_builds() {
|
||||
let mut main_window = tauri::utils::config::WindowConfig::default();
|
||||
main_window.label = "main".to_string();
|
||||
main_window.url = tauri::WebviewUrl::App(PathBuf::from("index.html"));
|
||||
|
||||
let mut config = tauri::utils::config::Config::default();
|
||||
config.app.windows = vec![main_window];
|
||||
config.build.dev_url =
|
||||
Some(tauri::Url::parse("http://127.0.0.1:3000/").expect("desktop dev url"));
|
||||
|
||||
let mut resolved = desktop_main_window_config_from_windows(&config.app.windows)
|
||||
.expect("main window config");
|
||||
if let Some(dev_url) = config.build.dev_url.as_ref() {
|
||||
resolved = apply_desktop_dev_url_to_main_window_config(resolved, dev_url);
|
||||
}
|
||||
|
||||
match resolved.url {
|
||||
tauri::WebviewUrl::External(url) => {
|
||||
assert_eq!(url.origin().ascii_serialization(), "http://127.0.0.1:3000");
|
||||
assert_eq!(url.path(), "/");
|
||||
assert_eq!(
|
||||
url.query_pairs()
|
||||
.find(|(key, _)| key == "hostShell")
|
||||
.map(|(_, value)| value.into_owned()),
|
||||
Some("tauri_desktop".to_string())
|
||||
);
|
||||
}
|
||||
other => panic!("unexpected dev main window url {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desktop_main_window_config_rejects_missing_main_window() {
|
||||
let mut secondary_window = tauri::utils::config::WindowConfig::default();
|
||||
|
||||
@@ -134,6 +134,14 @@ pub(crate) fn should_allow_desktop_webview_navigation(url: &Url) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
#[cfg(dev)]
|
||||
if url.scheme() == "http"
|
||||
&& url.host_str() == Some("127.0.0.1")
|
||||
&& url.port_or_known_default() == Some(3000)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if url.scheme() == "https" {
|
||||
let base_url = Url::parse(WEB_APP_ORIGIN).ok();
|
||||
return base_url
|
||||
@@ -249,6 +257,14 @@ mod tests {
|
||||
.expect("same-origin url");
|
||||
assert!(should_allow_desktop_webview_navigation(&same_origin_url));
|
||||
assert_eq!(desktop_external_navigation_url(&same_origin_url), None);
|
||||
|
||||
#[cfg(dev)]
|
||||
{
|
||||
let dev_url =
|
||||
Url::parse("http://127.0.0.1:3000/works/detail?work=PZ-1").expect("dev url");
|
||||
assert!(should_allow_desktop_webview_navigation(&dev_url));
|
||||
assert_eq!(desktop_external_navigation_url(&dev_url), None);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -3268,6 +3268,6 @@
|
||||
## 2026-06-21 Tauri devUrl 与 Vite 端口必须显式对齐
|
||||
|
||||
- 背景:`npm run desktop-shell:dev` 通过 Tauri `devUrl` 固定加载 `http://127.0.0.1:3000/`,但 Linux dev 端口段逻辑会把未显式指定的 `dev:web` 主站端口映射到用户端口段,例如 `10000+`。只在桌面壳 package script 里设置 `WEB_PORT=3000` 不会让 `scripts/dev.mjs` 把 Web 端口视为显式 CLI 参数,结果 Tauri 仍打开 3000,而 Vite 实际监听其它端口。
|
||||
- 决策:桌面壳 `beforeDevCommand` 必须执行 `npm --prefix ../.. run dev:web -- --web-port 3000 --strict-web-port`,用 CLI 参数锁定主站 Vite 端口并禁止静默漂移;`devUrl` 继续固定 `http://127.0.0.1:3000/`。如果 3000 被占用,应该释放端口后再启动桌面壳,而不是让 Vite 漂移后继续由 Tauri 加载旧端口。
|
||||
- 决策:桌面壳 `beforeDevCommand` 必须执行 `npm --prefix ../.. run dev:web -- --web-port 3000 --strict-web-port`,用 CLI 参数锁定主站 Vite 端口并禁止静默漂移;`devUrl` 继续固定 `http://127.0.0.1:3000/`。如果 3000 被占用,应该释放端口后再启动桌面壳,而不是让 Vite 漂移后继续由 Tauri 加载旧端口。由于主窗口设置了 `create=false` 并由 Rust 手动创建,`app.rs` 在 dev build 下必须把主窗口 URL 替换为 `build.devUrl` 后再补写 HostBridge query;release 仍从 `index.html` 打包资源进入。
|
||||
- 影响范围:`apps/desktop-shell/src-tauri/tauri.conf.json`、`apps/desktop-shell/scripts/check-config.mjs`、`scripts/dev.test.ts`、Expo / Tauri HostBridge 方案文档。
|
||||
- 验证方式:`npm run test -- scripts/dev.test.ts -t "Linux 桌面壳显式指定 web-port"`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。
|
||||
- 验证方式:`npm run test -- scripts/dev.test.ts -t "Linux 桌面壳显式指定 web-port"`、`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml desktop_main_window_config_uses_dev_url_in_dev_builds`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
@@ -2206,6 +2206,14 @@
|
||||
- 验证:`npm run test -- scripts/dev.test.ts -t "Linux 桌面壳显式指定 web-port"`、`npm run desktop-shell:typecheck`、实际启动时终端应显示 `[dev] web: http://127.0.0.1:3000`。
|
||||
- 关联:`apps/desktop-shell/src-tauri/tauri.conf.json`、`apps/desktop-shell/scripts/check-config.mjs`、`scripts/dev.mjs`。
|
||||
|
||||
## Tauri 手动创建主窗口时 devUrl 不会自动套到 index.html
|
||||
|
||||
- 现象:`npm run desktop-shell:dev` 启动后窗口地址显示 `http://tauri.localhost/index.html` 或 `tauri://localhost/index.html`,即使 Vite 已经在 `http://127.0.0.1:3000/` 正常监听。
|
||||
- 原因:桌面壳为了注册导航、下载、生命周期和托盘行为,把 Tauri 配置里的主窗口设为 `create=false`,再在 Rust `app.rs` 中用 `WebviewWindowBuilder::from_config(...)` 手动创建窗口。此时如果只读取 `app.windows[].url = index.html` 并补 HostBridge query,手动窗口会沿 release 入口走打包资源协议;Tauri CLI 的 `build.devUrl` 不会自动替换这份手动克隆后的窗口 URL。
|
||||
- 处理:`app.rs` 在 dev build 下必须先把主窗口 URL 替换为 `config.build.dev_url`,再调用 `desktop_window_config_with_runtime_platform(...)` 补写宿主上下文;`shell/navigation.rs` 也必须允许 dev build 下的 `http://127.0.0.1:3000` 留在 WebView 内,不要把自己的 Vite 首页当外链交给系统浏览器。release build 保持 `index.html` 打包入口。
|
||||
- 验证:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml desktop_main_window_config_uses_dev_url_in_dev_builds desktop_webview_navigation_stays_on_packaged_or_same_origin_pages`,实际启动时窗口应加载 `http://127.0.0.1:3000/...` 而不是 `tauri.localhost/index.html`。
|
||||
- 关联:`apps/desktop-shell/src-tauri/src/app.rs`、`apps/desktop-shell/src-tauri/src/shell/url.rs`、`apps/desktop-shell/src-tauri/src/shell/navigation.rs`、`apps/desktop-shell/src-tauri/tauri.conf.json`。
|
||||
|
||||
## 自动试玩退出不要回到生成页
|
||||
|
||||
- 现象:拼图草稿生成完成后自动进入试玩,用户从试玩退出或使用系统返回时落回生成进度页,页面还暴露“重新生成”按钮。
|
||||
|
||||
@@ -560,7 +560,7 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:桌面壳 bundle 图标集从现有真实品牌 PNG `apps/desktop-shell/src-tauri/icons/icon.png` 派生,补齐 `32x32.png`、`128x128.png`、`128x128@2x.png`、`icon.ico` 和 `icon.icns`,Tauri `bundle.icon` 同时声明这些平台图标。没有引入外部素材或占位图;`apps/desktop-shell/scripts/check-config.mjs` 会校验 PNG 尺寸、ICO 多尺寸头部、ICNS 容器长度和 bundle 图标列表,避免后续退回单图标或替换为非品牌素材。
|
||||
|
||||
2026-06-21 追加:桌面壳本地开发入口必须让 Tauri `devUrl` 和主站 Vite 实际监听端口保持一致。`apps/desktop-shell/src-tauri/tauri.conf.json` 的 `devUrl` 固定为 `http://127.0.0.1:3000/`,`beforeDevCommand` 必须执行 `npm --prefix ../.. run dev:web -- --web-port 3000 --strict-web-port`,不能只依赖 `WEB_PORT=3000` 环境变量;Linux 用户端口段分配会改写未显式指定的 Web 端口,裸 `dev:web` 可能漂移到 `10000+`,导致 Tauri 窗口加载 3000 时白屏或连接失败。3000 被占用时必须直接失败并提示释放端口,不能静默漂移。`apps/desktop-shell/scripts/check-config.mjs` 和 `scripts/dev.test.ts` 会反查该口径。
|
||||
2026-06-21 追加:桌面壳本地开发入口必须让 Tauri `devUrl` 和主站 Vite 实际监听端口保持一致。`apps/desktop-shell/src-tauri/tauri.conf.json` 的 `devUrl` 固定为 `http://127.0.0.1:3000/`,`beforeDevCommand` 必须执行 `npm --prefix ../.. run dev:web -- --web-port 3000 --strict-web-port`,不能只依赖 `WEB_PORT=3000` 环境变量;Linux 用户端口段分配会改写未显式指定的 Web 端口,裸 `dev:web` 可能漂移到 `10000+`,导致 Tauri 窗口加载 3000 时白屏或连接失败。3000 被占用时必须直接失败并提示释放端口,不能静默漂移。由于桌面壳主窗口设置了 `create=false` 并由 Rust 手动创建,`apps/desktop-shell/src-tauri/src/app.rs` 在 dev build 下必须把主窗口 URL 替换为 `build.devUrl` 后再补写 HostBridge query,不能继续用 release 的 `index.html`,否则 WebView 会落到 `tauri.localhost/index.html`。`apps/desktop-shell/scripts/check-config.mjs`、`scripts/dev.test.ts` 和桌面壳 Rust 单测会反查该口径。
|
||||
|
||||
2026-06-18 追加:移动壳生产包网络安全元数据显式收紧。Android `usesCleartextTraffic=false`,iOS `NSAppTransportSecurity.NSAllowsArbitraryLoads=false`,并设置 `ITSAppUsesNonExemptEncryption=false` 作为当前未接入自定义加密能力的出口合规声明;开发联调本机 Vite 仍通过显式 `EXPO_PUBLIC_GENARRATIVE_WEB_URL=http://127.0.0.1:3000/` 进入 development build,不把任意明文流量开关带进默认包配置。`apps/mobile-shell/scripts/check-config.mjs` 会校验这些网络安全字段。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user