Next.js + Tauri 2 用 Static Export 把 React 元框架装进桌面/移动端
1. 适配清单 Checklist
- 开启静态导出:
output: 'export'(Tauri 不支持 SSR 那种“必须有服务端”的方案)。 (Tauri) -
tauri.conf.json里把frontendDist指到../out(Next 静态导出目录)。 (Tauri) - 如果你用了
next/image,必须处理图片优化:静态导出下默认的图片优化 API 不可用,最简单就是images.unoptimized = true。 (Tauri) - 开发态资源路径要能解析:按官方建议加
assetPrefix,让 dev server 正确解析静态资源(尤其在非 localhost/移动端调试时)。 (Tauri)
2. Tauri 配置:src-tauri/tauri.conf.json
这段的意义是:tauri dev 先跑 Next dev server,再让 WebView 加载 devUrl;tauri build 先跑 Next build(生成 out),再把 out 打包进应用。Tauri CLI 正是按这些字段工作的。 (Tauri)
{
"build": {
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build",
"devUrl": "http://localhost:3000",
"frontendDist": "../out"
}
}
(Tauri)
提示:frontendDist 是相对 src-tauri/ 的路径,所以 Next 项目在根目录时通常就是 ../out。
3. Next.js 配置:next.config.mjs
这份配置解决三件大事:
- 强制静态导出
output: 'export' -
next/image走静态导出时禁用默认优化(否则直接报错) - 开发态设置
assetPrefix,避免资源解析错误(文档建议)
const isProd = process.env.NODE_ENV === 'production';
const internalHost = process.env.TAURI_DEV_HOST || 'localhost';
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true,
},
assetPrefix: isProd ? undefined : `http://${internalHost}:3000`,
};
export default nextConfig;
(Tauri)
补充理解一下 images.unoptimized:
静态导出下,Next 默认的 Image Optimization API(按需优化)不可用,所以必须禁用或换方案。官方错误说明写得很明确。 (nextjs.org)
4. package.json scripts:确保 Tauri 能“按脚本驱动”前端
你给的 scripts 很标准,Tauri CLI 会调用你在 beforeDevCommand/beforeBuildCommand 里写的命令,所以这里保证能跑就行:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"tauri": "tauri"
}
(Tauri)
5. 运行与打包:你只需要记住两条命令
-
开发:
-
cargo tauri dev(会先执行npm run dev,再加载http://localhost:3000) (Tauri)
-
-
构建:
-
cargo tauri build(会先执行npm run build,把静态导出生成到out/,再打包) (Tauri)
-
Next 的静态导出产物就是 out/,构建后你会看到 out/index.html、out/404.html 等文件结构。 (nextjs.org)
6. 你需要接受的“静态导出”边界
把 Next 变成静态站点后,这些能力要重新规划(否则你会在 build 时报错或运行时缺功能):
- 不依赖服务端运行时:SSR、需要 Node 运行时的 API Routes、中间件等都要迁移到独立后端服务(保持“客户端 ↔ API”的标准模式)。 (nextjs.org)
- 动态路由要可静态化:要么在构建期生成,要么改成纯客户端拉取数据再渲染(这和 Tauri 的模型更贴)。 (nextjs.org)
7. 常见坑与排查(很实用)
7.1 打包后白屏
优先按顺序查这三项:
-
out/是否真的生成(执行npm run build后是否有out/index.html)。 (nextjs.org) -
tauri.conf.json的frontendDist是否正确指向../out。 (Tauri) - 资源路径是否被你自定义了 basePath/assetPrefix 导致找不到 JS/CSS(打开 DevTools 看 Network 404)。
7.2 next/image 报错:Image Optimization 不兼容导出
这是经典报错场景,直接按文档处理:images.unoptimized: true 或换图片策略。 (nextjs.org)
7.3 开发态热更新不工作,和 assetPrefix 相关
社区里确实有人反馈:某些组合下 assetPrefix 会影响 hot reload 表现。你如果遇到“编译提示更新但页面不刷新”,可以把它当作已知问题来对待:
- 先尝试升级到更新版本的 Tauri/Next
- 或临时注释
assetPrefix验证是否是它引起 - 若必须保留资源解析能力,考虑把 dev server host 配置到可直连的内网地址并调整 devUrl(移动端场景更常见) (GitHub)