桌面壳持久化窗口状态
新增 Tauri window-state 插件并只保存主窗口大小、位置和最大化状态 收紧桌面壳依赖版本、插件顺序和三端文件结构门禁 同步宿主壳方案文档和团队决策记录
This commit is contained in:
@@ -529,6 +529,11 @@ for (const [sectionName, dependencyName, expectedLine] of [
|
||||
'tauri-plugin-single-instance',
|
||||
'tauri-plugin-single-instance = { version = "2.4.2", features = ["deep-link"] }',
|
||||
],
|
||||
[
|
||||
'dependencies',
|
||||
'tauri-plugin-window-state',
|
||||
'tauri-plugin-window-state = "2.4.1"',
|
||||
],
|
||||
]) {
|
||||
assertCargoDependencyLine(sectionName, dependencyName, expectedLine);
|
||||
}
|
||||
@@ -545,6 +550,7 @@ for (const [packageName, expectedVersion] of [
|
||||
['tauri-plugin-notification', '2.3.3'],
|
||||
['tauri-plugin-opener', '2.5.4'],
|
||||
['tauri-plugin-single-instance', '2.4.2'],
|
||||
['tauri-plugin-window-state', '2.4.1'],
|
||||
]) {
|
||||
assertCargoLockPackageVersion(packageName, expectedVersion);
|
||||
}
|
||||
@@ -561,6 +567,7 @@ for (const [dependencyName, expectedVersion] of [
|
||||
['tauri-plugin-notification', '2.3.3'],
|
||||
['tauri-plugin-opener', '2.5.4'],
|
||||
['tauri-plugin-single-instance', '2.4.2'],
|
||||
['tauri-plugin-window-state', '2.4.1'],
|
||||
]) {
|
||||
assertCargoLockDirectDependency(
|
||||
'genarrative-desktop-shell',
|
||||
@@ -1079,9 +1086,13 @@ const requiredRustHostModules = [
|
||||
'shell/tray.rs',
|
||||
'shell/url.rs',
|
||||
'shell/webview.rs',
|
||||
'shell/window_state.rs',
|
||||
];
|
||||
const requiredRustHostSnippets = [
|
||||
'tauri_plugin_single_instance::init',
|
||||
'desktop_window_state_plugin()',
|
||||
'tauri_plugin_window_state::Builder::default()',
|
||||
'StateFlags::SIZE | StateFlags::POSITION | StateFlags::MAXIMIZED',
|
||||
'tauri_plugin_deep_link::init()',
|
||||
'register_desktop_deep_link_events(app)',
|
||||
'register_desktop_deep_link_schemes(app)',
|
||||
@@ -1262,6 +1273,10 @@ if (!cargoManifest.includes('tauri-plugin-deep-link = "2.4.9"')) {
|
||||
throw new Error('desktop shell must depend on tauri-plugin-deep-link');
|
||||
}
|
||||
|
||||
if (!cargoManifest.includes('tauri-plugin-window-state = "2.4.1"')) {
|
||||
throw new Error('desktop shell must depend on tauri-plugin-window-state');
|
||||
}
|
||||
|
||||
if (
|
||||
!config.plugins ||
|
||||
!config.plugins['deep-link'] ||
|
||||
@@ -1278,11 +1293,28 @@ if (
|
||||
throw new Error('desktop shell must not configure updater without real signing and endpoint');
|
||||
}
|
||||
|
||||
if (
|
||||
main.indexOf('tauri_plugin_single_instance::init') >
|
||||
main.indexOf('tauri_plugin_clipboard_manager::init()')
|
||||
) {
|
||||
throw new Error('desktop shell must register the single-instance plugin first');
|
||||
const orderedDesktopPluginSnippets = [
|
||||
'tauri_plugin_single_instance::init',
|
||||
'desktop_window_state_plugin()',
|
||||
'tauri_plugin_deep_link::init()',
|
||||
'tauri_plugin_clipboard_manager::init()',
|
||||
'tauri_plugin_dialog::init()',
|
||||
'tauri_plugin_notification::init()',
|
||||
'tauri_plugin_opener::init()',
|
||||
];
|
||||
for (const pluginSnippet of orderedDesktopPluginSnippets) {
|
||||
if (!main.includes(pluginSnippet)) {
|
||||
throw new Error(`desktop shell main.rs missing plugin ${pluginSnippet}`);
|
||||
}
|
||||
}
|
||||
for (let index = 1; index < orderedDesktopPluginSnippets.length; index += 1) {
|
||||
const previousPlugin = orderedDesktopPluginSnippets[index - 1];
|
||||
const currentPlugin = orderedDesktopPluginSnippets[index];
|
||||
if (main.indexOf(previousPlugin) > main.indexOf(currentPlugin)) {
|
||||
throw new Error(
|
||||
`desktop shell plugin order drifted: ${previousPlugin} must be registered before ${currentPlugin}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (main.includes('single-instance",') || main.includes('"single-instance"')) {
|
||||
|
||||
Generated
+16
@@ -1317,6 +1317,7 @@ dependencies = [
|
||||
"tauri-plugin-notification",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-single-instance",
|
||||
"tauri-plugin-window-state",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3893,6 +3894,21 @@ dependencies = [
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-window-state"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73736611e14142408d15353e21e3cca2f12a3cfb523ad0ce85999b6d2ef1a704"
|
||||
dependencies = [
|
||||
"bitflags 2.13.0",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "2.11.2"
|
||||
|
||||
@@ -18,3 +18,4 @@ tauri-plugin-dialog = "2.7.1"
|
||||
tauri-plugin-notification = "2.3.3"
|
||||
tauri-plugin-opener = "2.5.4"
|
||||
tauri-plugin-single-instance = { version = "2.4.2", features = ["deep-link"] }
|
||||
tauri-plugin-window-state = "2.4.1"
|
||||
|
||||
@@ -14,6 +14,7 @@ use shell::webview::{
|
||||
replay_desktop_webview_state, should_allow_desktop_webview_download,
|
||||
should_allow_desktop_webview_navigation, should_replay_desktop_webview_state_on_page_load,
|
||||
};
|
||||
use shell::window_state::desktop_window_state_plugin;
|
||||
use tauri::webview::NewWindowResponse;
|
||||
|
||||
fn main() {
|
||||
@@ -27,6 +28,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
}))
|
||||
.plugin(desktop_window_state_plugin())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.plugin(tauri_plugin_clipboard_manager::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
|
||||
@@ -8,3 +8,4 @@ mod runtime;
|
||||
pub(crate) mod tray;
|
||||
mod url;
|
||||
pub(crate) mod webview;
|
||||
pub(crate) mod window_state;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
use tauri::plugin::TauriPlugin;
|
||||
use tauri::Runtime;
|
||||
use tauri_plugin_window_state::StateFlags;
|
||||
|
||||
pub(crate) fn desktop_window_state_plugin<R: Runtime>() -> TauriPlugin<R> {
|
||||
tauri_plugin_window_state::Builder::default()
|
||||
.with_state_flags(StateFlags::SIZE | StateFlags::POSITION | StateFlags::MAXIMIZED)
|
||||
.build()
|
||||
}
|
||||
@@ -2492,3 +2492,10 @@
|
||||
- 决策:`navigation.openNativePage` 仍只接受同源 H5 route,不新增真实原生页面、不放宽外域导航;通过校验后的目标 URL 在进入 WebView 前统一调用 `buildMobileShellUrl(...)` 重新附加当前 `MobileShellUrlOptions`,确保主动导航后的页面继续带 `clientRuntime=native_app`、`hostShell=expo_mobile`、真实平台、宿主版本和当前 capability 清单。
|
||||
- 影响范围:`apps/mobile-shell/src/host-bridge/`、`apps/mobile-shell/src/shell/ShellApp.tsx`、Expo / Tauri HostBridge 方案文档。
|
||||
- 验证方式:`npm run mobile-shell:test`、`npm run mobile-shell:typecheck`、`npm run check:native-shells`、`npm run typecheck -- --pretty false`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-06-18 桌面壳窗口状态持久化
|
||||
|
||||
- 背景:Tauri 桌面壳已经具备系统托盘、单实例、深链和受控 HostBridge 能力,但用户调整主窗口尺寸、位置或最大化状态后,重启桌面 App 仍回到固定初始窗口配置;如果直接保存完整窗口状态,又可能把托盘隐藏后的可见性状态带到下次启动。
|
||||
- 决策:桌面壳接入 `tauri-plugin-window-state`,并把插件配置收口到 `apps/desktop-shell/src-tauri/src/shell/window_state.rs`。只保存 `SIZE`、`POSITION` 和 `MAXIMIZED`,不保存 `VISIBLE`、`FULLSCREEN` 或 `DECORATIONS`;该能力属于宿主壳自身体验,不进入 HostBridge capability,不暴露窗口状态插件 command 给 H5。插件注册顺序固定为 single-instance 优先,其后才是 window-state、deep-link 和其它系统插件。
|
||||
- 影响范围:`apps/desktop-shell/src-tauri/Cargo.toml`、`apps/desktop-shell/src-tauri/Cargo.lock`、`apps/desktop-shell/src-tauri/src/main.rs`、`apps/desktop-shell/src-tauri/src/shell/window_state.rs`、`apps/desktop-shell/scripts/check-config.mjs`、Expo / Tauri HostBridge 方案文档。
|
||||
- 验证方式:`npm run desktop-shell:typecheck`、`npm run desktop-shell:test`、`npm run desktop-shell:build -- --no-bundle`、`npm run check:native-shells`、`npm run typecheck -- --pretty false`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
@@ -64,7 +64,7 @@ src/
|
||||
|
||||
已落地:`packages/shared/src/contracts/hostBridge.ts` 保存消息 envelope、method、payload 和错误码,H5、Expo 壳与 Tauri 壳共享同一份协议类型。
|
||||
|
||||
三端宿主桥接层按职责对齐命名:微信小程序页面路由仍保留在 `miniprogram/pages/*`,`miniprogram/host-bridge/protocol.js` 只沉淀微信壳能力、页面 URL、结果 hash / storage key 和分享消息类型等常量,`dispatch.js` 只作为 `protocol`、`webView`、`payment`、`shareGrid`、`subscribeMessage` 的薄索引,真实协议归一、支付 / 订阅 / 分享结果编解码仍分别在 `webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,不把微信小程序硬改成 Expo / Tauri 的 request 总线;Page 生命周期、`wx.*` 容器调用、WebView 容器行为和页面工厂统一放在 `miniprogram/shell/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,页面入口只做 `Page(createWechat...Page())` 装配。Expo 移动壳使用 `apps/mobile-shell/src/host-bridge/protocol.ts` 承接 envelope、request 校验、ok / failure 响应和 replay 基础类型,`capabilities.ts` 承接能力清单与 iOS 差异能力,`dispatch.ts` 承接 method 分发和宿主能力调用,`files.ts` / `share.ts` 分别承接文件和分享能力,`bridge.ts` 只作为 WebView message 入口、request id replay 编排和对外 facade;`apps/mobile-shell/App.tsx` 只装配 `apps/mobile-shell/src/shell/ShellApp.tsx`,由 `apps/mobile-shell/src/shell/*.ts(x)` 承接 WebView 容器、URL、导航、网络、生命周期、安全区和 WebView policy。Tauri 桌面壳使用 `apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs` 承接 envelope、method 白名单、request 校验和 replay 状态,`capabilities.rs` 承接能力清单,`dispatch.rs` 承接 method 分发和宿主能力调用,`files.rs` / `share.rs` 分别承接文件和分享能力,`mod.rs` 只保留模块声明、必要 re-export、`host_bridge_request` command facade 和 replay 编排;`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘和 WebView 门面,`main.rs` 只保留 Tauri builder / plugin / window 装配。
|
||||
三端宿主桥接层按职责对齐命名:微信小程序页面路由仍保留在 `miniprogram/pages/*`,`miniprogram/host-bridge/protocol.js` 只沉淀微信壳能力、页面 URL、结果 hash / storage key 和分享消息类型等常量,`dispatch.js` 只作为 `protocol`、`webView`、`payment`、`shareGrid`、`subscribeMessage` 的薄索引,真实协议归一、支付 / 订阅 / 分享结果编解码仍分别在 `webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,不把微信小程序硬改成 Expo / Tauri 的 request 总线;Page 生命周期、`wx.*` 容器调用、WebView 容器行为和页面工厂统一放在 `miniprogram/shell/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,页面入口只做 `Page(createWechat...Page())` 装配。Expo 移动壳使用 `apps/mobile-shell/src/host-bridge/protocol.ts` 承接 envelope、request 校验、ok / failure 响应和 replay 基础类型,`capabilities.ts` 承接能力清单与 iOS 差异能力,`dispatch.ts` 承接 method 分发和宿主能力调用,`files.ts` / `share.ts` 分别承接文件和分享能力,`bridge.ts` 只作为 WebView message 入口、request id replay 编排和对外 facade;`apps/mobile-shell/App.tsx` 只装配 `apps/mobile-shell/src/shell/ShellApp.tsx`,由 `apps/mobile-shell/src/shell/*.ts(x)` 承接 WebView 容器、URL、导航、网络、生命周期、安全区和 WebView policy。Tauri 桌面壳使用 `apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs` 承接 envelope、method 白名单、request 校验和 replay 状态,`capabilities.rs` 承接能力清单,`dispatch.rs` 承接 method 分发和宿主能力调用,`files.rs` / `share.rs` 分别承接文件和分享能力,`mod.rs` 只保留模块声明、必要 re-export、`host_bridge_request` command facade 和 replay 编排;`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs`、`window_state.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘、窗口状态持久化和 WebView 门面,`main.rs` 只保留 Tauri builder / plugin / window 装配。
|
||||
|
||||
## HostBridge 消息协议
|
||||
|
||||
@@ -189,6 +189,7 @@ Tauri 壳同样只负责桌面宿主能力,不承接玩法业务。
|
||||
- 崩溃上报、前端 analytics、桌面遥测日志、自动更新和渠道分发 SDK 都必须等真实端点、采集字段、用户同意、隐私策略、签名和发布流程确定后逐项接入;当前桌面壳不安装 Sentry、Datadog、PostHog、Segment、Amplitude、Bugsnag、OpenTelemetry、Tauri log / updater 等相关依赖。
|
||||
- 桌面壳和根 H5 包不安装 `@tauri-apps/api` 或 `@tauri-apps/plugin-*` JS guest 包;生产 H5 只通过 Tauri 注入的 `window.__TAURI__.core.invoke('host_bridge_request', request)` 进入 HostBridge。opener、clipboard、dialog、notification 等能力只保留 Rust Cargo 插件,由 Rust 内部分发并受 capability 白名单约束。
|
||||
- 桌面深链只作为宿主启动 / 唤醒入口处理,不进入 HostBridge capability,也不把 deep-link 插件 command 授权给 H5。Tauri 只注册 `genarrative` scheme,并接受同源 `https://app.genarrative.world` URL;壳层会把目标路径归一为带 `native_app`、`tauri_desktop` 和真实 capability 清单的同源 H5 URL,外域、明文协议和危险协议直接丢弃。
|
||||
- 桌面窗口状态持久化属于宿主壳自有体验,不进入 HostBridge capability,也不开放窗口状态插件 command 给 H5。Tauri 壳只保存主窗口大小、位置和最大化状态,不保存可见性、全屏或装饰状态,避免托盘隐藏窗口后下次启动被恢复成隐藏状态。
|
||||
|
||||
桌面 release 和 dev 模式:
|
||||
|
||||
@@ -351,6 +352,8 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 单实例。用户重复启动桌面 App 时,新实例会退出并唤醒已有主窗口;该回调只执行显示、取消最小化和聚焦主窗口,不把第二实例的命令行参数或工作目录作为事件透传给 H5。Windows / Linux 上由单实例插件的 `deep-link` feature 把二次实例 URL 交给 deep-link 插件,仍由 `shell/deep_link.rs` 做受控归一。
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 窗口状态持久化。`shell/window_state.rs` 只配置 `tauri-plugin-window-state` 保存主窗口大小、位置和最大化状态,并排除可见性、全屏和装饰状态;插件注册顺序固定为 single-instance 优先,其后才是窗口状态、deep-link 和其它系统能力插件。该能力不进入 HostBridge 清单,不向 H5 暴露任意窗口状态读写,也不改变托盘关闭隐藏、单实例唤醒和托盘恢复主窗口的既有语义。
|
||||
|
||||
2026-06-18 追加:桌面壳接入 Tauri deep-link 插件,但不开放插件 JS guest API,也不把 deep-link 命令加入 capability。桌面配置只注册 `genarrative` scheme;Rust 层只接受 `genarrative://open/...`、`genarrative://app/...`、`genarrative://<path>` 和 `https://app.genarrative.world/...`,统一跳到同源 H5 路径并补写 `clientRuntime=native_app`、`hostShell=tauri_desktop`、当前平台、版本与真实 `hostCapabilities`。外域、`http:`、`mailto:`、`javascript:`、`file:` 等来源不进入主 WebView。
|
||||
|
||||
2026-06-18 追加:桌面壳安装包身份固定为 `world.genarrative.desktop`,产品名为 `Genarrative`,Tauri、Node package 与 Cargo package 版本统一为 `0.1.0`。Release 主窗口只能从打包进二进制的 `index.html` 进入根 `dist` H5 资产,dev URL 只能指向本机 Vite 调试入口;CSP 必须保持 `script-src 'self'`,不得加入 `unsafe-eval`、`tauri:` 或 `file:` 这类扩大桌面攻击面的来源。当前不配置自动更新器,直到存在真实更新端点、签名密钥和发布流程再接入;`apps/desktop-shell/scripts/check-config.mjs` 会校验这些包身份、版本、CSP 和 updater 禁用约束。
|
||||
@@ -371,7 +374,7 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:桌面壳 JS guest 依赖进入门禁。`apps/desktop-shell/package.json`、根 H5 `package.json` 和根 `package-lock.json` 不得安装或解析 `@tauri-apps/api` 或任何 `@tauri-apps/plugin-*` 包,避免生产前端绕过 `nativeAppHostBridge` 直接调用 Tauri JS 客户端 API;Tauri CLI 仍只作为构建工具留在 devDependencies,桌面系统能力继续由 Rust 侧 Cargo 插件和唯一 `host_bridge_request` command 承接。
|
||||
|
||||
2026-06-18 追加:桌面壳关键依赖版本进入配置门禁。`apps/desktop-shell/package.json` 与根 `package.json` 的 Tauri CLI 和 TypeScript 版本必须一致;根 `package-lock.json` 里的实际解析版本也必须一致;`src-tauri/Cargo.toml` 的 `tauri-build`、`tauri`、`base64`、`serde`、`serde_json` 以及 clipboard、dialog、notification、opener、single-instance 插件版本和 Tauri `tray-icon` feature 都由 `apps/desktop-shell/scripts/check-config.mjs` 固定检查,`src-tauri/Cargo.lock` 中桌面壳 direct dependency 的实际解析版本也必须同步受检。升级这些依赖必须同步审查 capability、CSP、唯一 command、插件初始化、release build smoke 和本文档。
|
||||
2026-06-18 追加:桌面壳关键依赖版本进入配置门禁。`apps/desktop-shell/package.json` 与根 `package.json` 的 Tauri CLI 和 TypeScript 版本必须一致;根 `package-lock.json` 里的实际解析版本也必须一致;`src-tauri/Cargo.toml` 的 `tauri-build`、`tauri`、`base64`、`serde`、`serde_json` 以及 clipboard、dialog、notification、opener、single-instance、window-state 插件版本和 Tauri `tray-icon` feature 都由 `apps/desktop-shell/scripts/check-config.mjs` 固定检查,`src-tauri/Cargo.lock` 中桌面壳 direct dependency 的实际解析版本也必须同步受检。升级这些依赖必须同步审查 capability、CSP、唯一 command、插件初始化、release build smoke 和本文档。
|
||||
|
||||
2026-06-18 追加:H5 到 Tauri 的 command 名进入共享契约。`packages/shared/src/contracts/hostBridge.ts` 导出 `HOST_BRIDGE_TAURI_COMMAND='host_bridge_request'`,`nativeAppHostBridge` 只能通过该常量调用 Tauri 注入的 `core.invoke`;桌面壳配置检查会对齐共享常量、Tauri build manifest、Rust `generate_handler!` 和 H5 transport,禁止 H5 侧写死或调用其它 Tauri command。
|
||||
|
||||
@@ -415,7 +418,7 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:移动壳 HostBridge 消息入口增加来源校验。`onMessage` 不只依赖导航拦截和 `originWhitelist`,还会读取 `event.nativeEvent.url`,只有同源主站页面才能进入 `handleMobileHostBridgeMessage`;`about:blank`、外域 URL、协议降级或危险协议页面发来的消息全部丢弃,不返回 HostBridge 错误细节。该校验与 `navigation.openNativePage` 共用同源规则,防止历史中间页或异常页面在带完整 HostBridge 的 WebView 中发起宿主能力请求。
|
||||
|
||||
2026-06-18 追加:微信、移动端和桌面端桥接层文件结构按职责对齐。微信小程序的 `web-view`、支付、九宫切图和订阅消息桥接逻辑统一迁入 `miniprogram/host-bridge/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,页面目录只保留页面生命周期、WXML/WXSS 和装配;移动壳拆成 `apps/mobile-shell/src/host-bridge/protocol.ts`、`files.ts`、`share.ts` 和 facade `bridge.ts`,与桌面端 `host_bridge/protocol.rs`、`files.rs`、`share.rs`、`mod.rs` 对齐;移动壳根 `App.tsx` 也保持薄入口,只装配 `src/shell/ShellApp.tsx`,WebView 容器、深链、网络、生命周期和安全策略全部留在 `src/shell/`;桌面壳 Rust 源码拆成 `apps/desktop-shell/src-tauri/src/host_bridge/*.rs` 与 `apps/desktop-shell/src-tauri/src/shell/*.rs`,其中 `runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘和 WebView 门面,薄 `main.rs` 只声明两个模块并装配 Tauri builder / plugin / window。根级 `npm run check:native-shells` 会锁定三端桥接层目录清单,避免后续把能力逻辑重新散落到页面、移动入口或桌面入口。
|
||||
2026-06-18 追加:微信、移动端和桌面端桥接层文件结构按职责对齐。微信小程序的 `web-view`、支付、九宫切图和订阅消息桥接逻辑统一迁入 `miniprogram/host-bridge/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,页面目录只保留页面生命周期、WXML/WXSS 和装配;移动壳拆成 `apps/mobile-shell/src/host-bridge/protocol.ts`、`files.ts`、`share.ts` 和 facade `bridge.ts`,与桌面端 `host_bridge/protocol.rs`、`files.rs`、`share.rs`、`mod.rs` 对齐;移动壳根 `App.tsx` 也保持薄入口,只装配 `src/shell/ShellApp.tsx`,WebView 容器、深链、网络、生命周期和安全策略全部留在 `src/shell/`;桌面壳 Rust 源码拆成 `apps/desktop-shell/src-tauri/src/host_bridge/*.rs` 与 `apps/desktop-shell/src-tauri/src/shell/*.rs`,其中 `runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs`、`window_state.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘、窗口状态持久化和 WebView 门面,薄 `main.rs` 只声明两个模块并装配 Tauri builder / plugin / window。根级 `npm run check:native-shells` 会锁定三端桥接层目录清单,避免后续把能力逻辑重新散落到页面、移动入口或桌面入口。
|
||||
|
||||
### Phase 4:宿主能力扩展
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ const expectedDesktopShellRustFiles = [
|
||||
'tray.rs',
|
||||
'url.rs',
|
||||
'webview.rs',
|
||||
'window_state.rs',
|
||||
];
|
||||
const productionShellExtensions = new Set([
|
||||
'.json',
|
||||
|
||||
Reference in New Issue
Block a user