从 Tauri 2.0 Beta 升级到 2.0 Release Candidate Capabilities 权限前缀与内置 Dev Server 网络策略变
1. 一句话结论:这次升级你要重点改哪两处
Capabilities(权限配置)
旧写法:path:default、window:default ……
新写法:要么统一加 core: 前缀,例如 core:path:default
要么直接用一个更省事的集合权限:core:default
内置开发服务器(尤其 iOS 真机)
以前你可能通过 TAURI_ENV_PLATFORM 判断 android/ios,再去暴露 0.0.0.0、算内网 IP、配 HMR
现在更推荐直接用 TAURI_DEV_HOST:能连 localhost 就别搞全网暴露;需要暴露时,Tauri 会告诉你应该用哪个 host
2. 自动迁移优先:先跑 migrate,再做人工复核
官方建议的升级方式是先用 v2 CLI 的 migrate 做自动改动,然后再手动处理剩余 breaking changes。
cargo install tauri-cli --version "^2.0.0" --locked
cargo tauri migrate
建议你把这条命令放在一个独立分支上跑(比如 chore/tauri-rc-migrate),这样 diff 会非常清晰。
迁移后你至少要人工检查两件事:
-
src-tauri/capabilities/*.json(或相应能力文件)里的 permissions 是否符合新规则 - 前端 dev server 配置是否已切换到
TAURI_DEV_HOST逻辑
3. Breaking Change 1:核心插件权限标识统一加 “core:” 前缀
3.1 发生了什么
从 beta 到 RC,Tauri 调整了“内置核心插件(core plugins)”在 capabilities 里被引用的方式。
你原来 capability 里写的这些:
"permissions": [
"path:default",
"event:default",
"window:default",
"app:default",
"image:default",
"resources:default",
"menu:default",
"tray:default"
]
需要改成加 core: 前缀:
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:app:default",
"core:image:default",
"core:resources:default",
"core:menu:default",
"core:tray:default"
]
3.2 更推荐的写法:直接用 core:default
为了减少样板代码,RC 增加了一个“特殊集合权限”core:default,它包含所有 core plugins 的默认权限。
也就是说,上面那一长串可以直接写成:
"permissions": [
"core:default"
]
推荐策略:
- 你只是需要 core 插件的默认能力:用
core:default,最省心 - 你项目对权限非常敏感,需要精确控制:继续按需列出
core:*的细粒度权限
迁移验收点:
- 升级后如果出现“前端调用 core API 失败 / 权限不足”的报错,第一时间就去看 capability 文件里是不是还残留
path:default这种旧标识
4. Breaking Change 2:内置开发服务器网络暴露策略改变(移动端调试更安全)
4.1 发生了什么
RC 对内置移动端开发服务器做了网络暴露策略调整:
移动端开发服务器不再默认“全网暴露并转发流量”,而是更倾向于让设备通过更安全、更直接的方式连接到本机服务。
这会直接影响你的前端 dev server 配置方式,因为以前很多模板都在做这些事:
-
host: '0.0.0.0'(让局域网设备都能连) - 用
internal-ip算出本机 IPv4 作为 HMR host - 用
TAURI_ENV_PLATFORM判断 android/ios 就强制启用“移动端模式”
RC 的思路是:能用 localhost 就用 localhost,只有在必要时才用特定 host,并且把这个 host 通过 TAURI_DEV_HOST 传给前端工具链。
4.2 iOS 真机特别说明:TAURI_DEV_HOST + Xcode TUN 地址
目前这个“更安全的连接方式”在 iOS(直接连真机或从 Xcode 跑)场景下不一定能自动生效。官方给的解决方案思路是:
1)打开 Xcode,让 macOS 和 iOS 设备建立连接通道
2)运行 tauri ios dev --force-ip-prompt
3)选择 iOS 设备的 TUN 地址(通常结尾是 ::2)
这部分你不需要把细节写死在 Vite 配置里,关键是:让前端 dev server 读取 TAURI_DEV_HOST。
5. Vite 迁移:从 “internal-ip + TAURI_ENV_PLATFORM” 到 “TAURI_DEV_HOST”
这是最实用的一段,因为它直接决定你真机调试是否顺畅。
5.1 Beta 常见写法(旧)
核心特征:
- 通过
TAURI_ENV_PLATFORM判断 mobile - mobile 时用
0.0.0.0 - HMR host 用
internal-ip算出来
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { internalIpV4Sync } from 'internal-ip';
const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM);
export default defineConfig({
plugins: [svelte()],
clearScreen: false,
server: {
host: mobile ? '0.0.0.0' : false,
port: 1420,
strictPort: true,
hmr: mobile
? {
protocol: 'ws',
host: internalIpV4Sync(),
port: 1421,
}
: undefined,
},
});
5.2 RC 推荐写法(新)
核心特征:
- 直接读取
TAURI_DEV_HOST - 有 host 才暴露网络与启用 HMR host
- 不再需要
internal-ip依赖 - 示例里 HMR 端口从
1421改到了1430(按你的内容照搬)
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
const host = process.env.TAURI_DEV_HOST;
export default defineConfig({
plugins: [svelte()],
clearScreen: false,
server: {
host: host || false,
port: 1420,
strictPort: true,
hmr: host
? {
protocol: 'ws',
host: host,
port: 1430,
}
: undefined,
},
});
迁移验收点:
- 你的 package.json 里可以去掉
internal-ip - 真机调试时,如果 Tauri 注入了
TAURI_DEV_HOST,HMR 也会跟着正确走 - 如果你之前硬编码了
0.0.0.0,升级后建议先移除,避免无意义扩大暴露面
6. 升级后的快速自检清单(5 分钟验收)
1)Capabilities 是否已迁移
- 搜索 capability 文件里是否还有
path:default这种旧值 - 优先改成
core:default或core:*:default
2)前端 dev server 是否已切 TAURI_DEV_HOST
- 搜索
TAURI_ENV_PLATFORM、internal-ip、internalIpV4Sync - 替换为
const host = process.env.TAURI_DEV_HOST
3)真机(尤其 iOS)是否能连上 dev server
- 若连接失败,按官方提示用 Xcode 建连接后
tauri ios dev --force-ip-prompt选 TUN::2地址 - 确认此时
TAURI_DEV_HOST有值,并被 Vite 使用
7. 常见踩坑与解决思路
权限全挂但你以为是代码问题
表现:invoke / core API 提示权限不足或无权限
处理:先别改业务代码,先把 capabilities 的 core 前缀或 core:default 处理好
HMR 能开但页面不热更
表现:能打开页面但热更新没反应
处理:看 Vite server.hmr.host 是否仍然是旧的内网 IP 逻辑;改为 TAURI_DEV_HOST
依赖没删干净导致 lockfile 混乱
表现:internal-ip 还在,或者打包时出现 node 依赖冲突
处理:删除 internal-ip、重新安装依赖,确保 lockfile 与新配置一致