Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

多平台工作区

当前 Oak 应用把业务源码和平台壳分开组织:src 保存实体、业务逻辑、页面和组件,Web、微信小程序、React Native、Desktop 各自拥有独立 workspace。新应用默认只创建 Web;其它平台在真正需要时通过 oak-cli add 加入。

平台模型

平台添加命令构建目标说明
Web默认生成,或 oak-cli add web web2web浏览器 renderer
微信小程序oak-cli add mp wechatMpmp / wechatMpVite 小程序编译与微信产物
React Nativeoak-cli add rn nativern / nativeiOS、Android 原生应用
Desktopoak-cli add desktop desktopdesktop默认 Tauri,也支持 Electron

mprn 是命令别名,内部会规范为 wechatMpnative。workspace 名可以自定义,CLI 会把 --subDir 写入对应 npm script;不要在业务代码里假设目录一定叫 wechatMpnativedesktop

添加 workspace 后重新执行:

npm install
npm run make:locale

oak-cli add 会同步依赖、平台 TypeScript 配置和 npm scripts,但不会替你安装刚写入 package.json 的依赖。

Desktop:Tauri 与 Electron

创建 Tauri workspace:

oak-cli add desktop desktop

创建 Electron workspace:

oak-cli add desktop desktop-electron --runtime electron

不传 --runtime 时默认使用 Tauri。生成后会出现类似脚本:

{
    "start:desktop:desktop": "oak-cli start --target desktop --render tauri --subDir desktop",
    "build:desktop:desktop": "oak-cli build --target desktop --render tauri --subDir desktop"
}

Desktop 是 Web renderer 的一种运行形态:编译时 OAK_PLATFORM 仍为 web,再通过 OAK_RENDER=tauriOAK_RENDER=electron 区分原生壳。oak-general-business 中的应用仍使用 Web Application 类型,并通过 config.renderidentifyId 区分浏览器、Tauri、Electron。不要创建自定义 desktop AppType。

生成内容

每个 Desktop workspace 都包含 .oak-desktop.json

{
    "schemaVersion": 1,
    "runtime": "tauri",
    "identifyId": "00000000-0000-4000-8000-000000000000"
}

实际 identifyId 由 CLI 生成并保持稳定。它用于后端匹配对应 Desktop Application,不是用户登录凭证,也不应交给 renderer 业务代码自行修改或伪造。

Tauri workspace 还包含 src-tauri Rust 工程;Electron workspace 包含薄的 main/preload 入口和 electron-builder.yml。两种运行时共用 Desktop 页面、Fluent UI 壳、路由、权限菜单、系统主题和离线 locale 装载方式。

启动与构建

npm run server:start
npm run start:desktop:desktop

Desktop 命令会先启动 Vite renderer,等待端口可访问,再启动 Tauri 或 Electron;任一子进程退出时会清理另一侧。Tauri 使用 tauri.conf.json 的固定 devUrl 端口,默认是 1420;Electron 从指定端口或 1420 开始寻找空闲端口。

生产构建:

npm run build:desktop:desktop

Tauri 构建 renderer 后调用 Tauri CLI;Electron 构建 renderer 后调用 electron-builder。Desktop 产物必须离线可启动,所以生产 renderer 不使用 Web CDN external,React 等运行依赖会进入本地 bundle。

后端访问与离线启动

Web 和 Desktop 都从 src/configuration/access.ts 解析 Oak 后端 URL。不要再从 common.ts 单独派生 Desktop 端口,也不要把第二份后端地址写进 Rust、Electron main 或 CSP。

Desktop 对配置命中的 localhost / 127.0.0.1 Oak 请求使用原生桥接,并注入 renderer 与 application 识别元数据;其它外部 URL 继续使用浏览器 fetch。identifyId 只应在原生边界注入。

Desktop 启动和构建会先生成并复制 src/data/i18n.json。Tauri 把它嵌入资源,Electron 把它打进应用包;Locales feature 会把离线数据同步进正常 Cache。缺少该文件时,先执行:

npm run make:locale

应用解析还可以保存并回放已验证的 Application 查询快照,在真实网络异常时支持离线启动;普通业务查询不会因此自动变成离线数据库。

Desktop render 选择

普通模块选择顺序以 Desktop 和操作系统入口优先,然后回退到 Web:

.desktop.* -> .windows|.macos|.linux.* -> .web.* -> 普通入口

Oak 页面和组件 render 的回退顺序是:

render.desktop.tsx
render.windows.tsx / render.macos.tsx / render.linux.tsx
web.pc.tsx
web.tsx

共享组件通常不需要专门写 Desktop render;只有桌面交互确实不同才增加 render.desktop.tsx 或操作系统入口。

微信小程序 workspace

oak-cli add mp wechatMp
npm install
npm run start:mp:wechatMp

当前 Vite 小程序构建会根据页面配置生成 canonical route map。业务导航应使用 Oak navigator 的 /namespace/page 逻辑路径;静态的 wx.navigateToredirectToreLaunchswitchTab URL 也会尝试在构建时改写。不要手写 /pages/.../index 或分包产物路径。

switchTab 不能携带 query 或 state。动态拼接且无法静态识别的路径会产生 warning,应改为 Oak navigator 或明确的静态路由。

小程序还支持:

  • index.config.ts 生成页面/组件 JSON;
  • XML/WXML 表达式、事件、properties 和 class 类型检查;
  • 分包与独立分包 chunk、asset、WXS/i18n 输出;
  • 构建产物图片压缩和 Node polyfill 白名单;
  • bundle treemap、分包统计和反向依赖图。

这些编译选项见编译与构建配置

React Native workspace

oak-cli add rn native
npm install
npm run start:native:native
npm run run:android:native

iOS 使用 run:ios:<workspace>。Metro 只负责 JavaScript 开发服务,原生 SDK、签名、证书和渠道包仍由 React Native、Android Studio 和 Xcode 工程管理。

当前 workspace 同时生成生产构建脚本:

npm run build:native:native:android
npm run build:native:native:ios

Android 命令会继续进入原生依赖 codegen、Metro bundle 与 Gradle release 构建;没有配置 ANDROID_HOMEnative/android/local.properties 时会在 SDK 检查处失败。不要把 local.properties、keystore、签名密码或渠道凭证提交到仓库。

页面/组件优先使用 render.native.tsxrender.native.scss,需要平台差异时再增加 render.ios.tsxrender.android.tsx

多 workspace 注意事项

  • locale、router、alias 和 TypeScript 配置根据 npm scripts 中的 --target--subDir 发现 workspace,不应硬编码默认目录。
  • 新 workspace 使用自己的 tsconfig.json;根配置主要负责共享源码和编辑器聚合。
  • oak-cli add --from <dir> 会复制一个完整 workspace,不再覆盖内置平台 scaffold;传入目录必须自己满足目标运行时合同。
  • 页面、菜单、route access 和 namespace config 仍来自共享 src/pages/**/index.config.ts,平台 workspace 消费生成结果,不应在运行时重新扫描源码。