Next.js
本指南将引导您使用 React 框架 Next.js 创建您的第一个 Tauri 应用。
在继续之前,请确保您已完成 前提条件 以拥有一个可用的开发环境。
Tauri 是一个用于使用任何前端框架和 Rust 内核构建桌面应用程序的框架。每个应用程序包含两个部分:
- 创建窗口并将原生功能暴露给这些窗口的 Rust 二进制文件
- 您选择的在其窗口内生成用户界面的前端
接下来,我们将首先搭建前端,设置 Rust 项目,最后向您展示如何在这两者之间进行通信。
以下是我们将构建内容的预览:
创建前端
Next.js 是一个 React 框架,它具有服务器端渲染 (SSR) 和静态站点生成 (SSG) 功能。为了使 Next.js 与 Tauri 一起工作,我们将使用 SSG 模式,因为它只生成可以包含在最终二进制文件中的静态文件。
Next.js 带有一个类似于 create-tauri-app
的脚手架工具,可以快速从许多预定义模板中设置新项目。在本指南中,我们将对所有问题使用建议的默认值,包括 TypeScript 支持和在 v13.4 中稳定的新 App Router
功能。如果您使用的是旧的 pages/
目录,或者在 app/
目录之上使用,您仍然需要更改如 Next.js 静态导出 部分所述的配置,但是您使用 Tauri 特定 JS API 的方式将与下面描述的不同。
- npm
- Yarn
- pnpm
- Bun
npx create-next-app@latest --use-npm
yarn create next-app --use-yarn
pnpm create next-app --use-pnpm
bunx create-next-app --use-bun
- 项目名称
这将是您项目的名称。它对应于此实用程序将创建的文件夹的名称,但对您的应用程序没有其他影响。您可以在此处使用任何您想要的名称。
如果您使用的是 TypeScript,您可能希望排除 src-tauri
目录,以防止 Next.js/TypeScript 扫描它。您的 tsconfig.json
文件应该已经包含一个 "exclude"
部分,您可以在其中添加它。
"exclude": [
"node_modules",
"src-tauri"
]
Next.js 静态导出
因为 Tauri 没有 Node.js 运行时,您必须将 Next.js 设置为 SSG/SPA 模式。这通常会导致页面加载速度更快,但也有一些需要注意的警告,因此我们建议您仔细阅读 Next.js 关于 静态导出 的官方文档。
这些文档还显示了一个必需的配置更改,对于 Tauri + Next.js 应用程序,我们始终必须进行此更改。为此,请编辑项目根目录中的 next.config.js
文件并添加以下内容:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
}
module.exports = nextConfig
这将更改 next build
的行为,以生成包含应用程序的 HTML/CSS/JS 资源的 out/
文件夹,而不是将它们写入特定于 Next.js 运行时的 .next/
目录。
还有更多可能的配置选项,因此请确保阅读上面提到的 静态导出 文档,并根据项目的需要调整配置文件。
创建 Rust 项目
每个 Tauri 应用程序的核心都是一个 Rust 二进制文件,它通过名为 tauri
的 Rust crate 管理窗口、webview 和对操作系统的调用。此项目由 Cargo 管理,Cargo 是 Rust 的官方包管理器和通用构建工具。
我们的 Tauri CLI 在后台使用 Cargo,因此您很少需要直接与它交互。Cargo 还有许多通过我们的 CLI 未公开的更有用的功能,例如测试、代码检查和格式化,因此请参阅其 官方文档 以了解更多信息。
如果您尚未安装 Tauri CLI,可以使用以下命令之一进行安装。不确定使用哪个?查看 常见问题解答条目。
- npm
- Yarn
- pnpm
- Bun
- Cargo
npm install --save-dev @tauri-apps/cli@">1.0.0"
package.json
文件中的 "scripts" 部分。"scripts": {
"tauri": "tauri"
}
yarn add -D @tauri-apps/cli@^1.0.0
pnpm add -D @tauri-apps/cli@1
bun add -D @tauri-apps/[email protected]
cargo install tauri-cli --version "^1.0.0"
要搭建一个预先配置为使用 Tauri 的最小 Rust 项目,请打开终端并运行以下命令:
- npm
- Yarn
- pnpm
- Bun
- Cargo
npm run tauri init
yarn tauri init
pnpm tauri init
bunx tauri init
cargo tauri init
它将引导您完成一系列问题:
- 您的应用程序名称是什么?
这将是您最终捆绑包的名称,也是操作系统将您的应用程序称为什么。您可以在此处使用任何您想要的名称。 - 窗口标题应是什么?
这将是默认主窗口的标题。您可以在此处使用任何您想要的标题。 - 您的 Web 资源 (HTML/CSS/JS) 相对于将要创建的
<当前目录>/src-tauri/tauri.conf.json
文件位于哪个位置?
这是 Tauri 在为 **生产环境** 构建时将从中加载前端资源的路径。为此值使用../out
。 - 您的开发服务器的 URL 是什么?
这可以是 Tauri 在 开发期间将加载的 URL 或文件路径。.为此值使用https://127.0.0.1:3000
。 - 您的前端开发命令是什么?
这是用于启动前端开发服务器的命令。为此值使用npm run dev
(确保将其调整为使用您选择的包管理器)。 - 您的前端构建命令是什么?
这是构建前端文件的命令。为此值使用npm run build
(确保将其调整为使用您选择的包管理器)。
如果您熟悉 Rust,您会注意到 tauri init
看起来和工作方式与 cargo init
非常相似。如果您更喜欢完全手动设置,则可以使用 cargo init
并添加必要的 Tauri 依赖项。
tauri init
命令生成一个名为 src-tauri
的文件夹。对于 Tauri 应用程序,通常将所有核心相关文件放在此文件夹中。让我们快速浏览一下此文件夹的内容:
Cargo.toml
Cargo 的清单文件。您可以声明您的应用程序依赖的 Rust crate、关于您的应用程序的元数据等等。有关完整参考,请参阅 Cargo 的清单格式。tauri.conf.json
此文件允许您配置和自定义 Tauri 应用程序的各个方面,从应用程序的名称到允许的 API 列表。有关支持选项的完整列表以及每个选项的详细说明,请参阅 Tauri 的 API 配置。src/main.rs
这是您的 Rust 程序的入口点,也是我们引导进入 Tauri 的地方。您将在此处找到两个部分:src/main.rs#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
tauri::Builder::default()
.run(tauri::generate_context!())
.expect("error while running tauri application");
}以
cfg! 宏
开头的行只有一个作用:它禁用了在 Windows 上运行捆绑应用程序时通常会弹出的命令提示符窗口。如果您在 Windows 上,请尝试注释掉它并查看会发生什么。main
函数是入口点,也是程序运行时调用的第一个函数。图标
您可能想要一个漂亮的应用程序图标!为了让您快速上手,我们包含了一组默认图标。您应该在发布应用程序之前更换这些图标。在 Tauri 的 图标特性指南 中了解有关各种图标格式的更多信息。
现在我们已经搭建了前端并初始化了 Rust 项目,您几乎可以运行您的应用程序了。您的 tauri.conf.json
文件应该如下所示:
{
"build": {
"beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev",
"devPath": "https://127.0.0.1:3000",
"distDir": "../out"
},
就是这样!现在您可以在终端中运行以下命令来启动应用程序的开发版本:
- npm
- Yarn
- pnpm
- bun
- Cargo
npm run tauri dev
yarn tauri dev
pnpm tauri dev
bunx tauri dev
cargo tauri dev
调用命令
Tauri 允许您使用原生功能增强您的前端。我们称这些为 命令,本质上是您可以从前端 JavaScript 调用的 Rust 函数。这使您可以以更高效的 Rust 代码处理繁重的处理或对操作系统的调用。
让我们做一个简单的例子:
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
命令就像任何常规 Rust 函数一样,附加了 #[tauri::command]
属性宏,允许您的函数与 JavaScript 上下文通信。
最后,我们还需要告诉 Tauri 我们新创建的命令,以便它可以相应地路由调用。这可以通过组合使用 `invoke_handler()` 函数和下面看到的 `generate_handler![]` 宏来完成。
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
现在您可以从前端调用您的命令了!
要调用我们新创建的命令,我们将使用 @tauri-apps/api
JavaScript 库。它通过方便的 JavaScript 抽象提供了对核心功能(例如窗口操作、文件系统等)的访问。您可以使用您最喜欢的 JavaScript 包管理器安装它。
- npm
- Yarn
- pnpm
- Bun
npm install @tauri-apps/api@">1.0.0"
yarn add @tauri-apps/api@^1.0.0
pnpm add @tauri-apps/api@1
bun add @tauri-apps/[email protected]
需要注意的一点是,所有 Tauri 的 JS API 都需要访问仅限浏览器的 API,这意味着它们只能在 客户端组件 中使用。如果您不需要服务器组件,可以在 `app/page.tsx` 文件的顶部添加 `'use client'`,但是在这个指南中,我们将创建一个单独的组件,这样我们就不用转换整个应用程序了。
'use client'
import { useEffect, useState } from 'react';
import { invoke } from '@tauri-apps/api/tauri'
export default function Greet() {
const [greeting, setGreeting] = useState('');
useEffect(() => {
invoke<string>('greet', { name: 'Next.js' })
.then(result => setGreeting(result))
.catch(console.error)
}, [])
// Necessary because we will have to use Greet as a component later.
return <div>{greeting}</div>;
}
现在,我们将在 `app/page.tsx` 中的默认 `Home` 组件中使用此组件。请注意,它必须位于实际的组件树中,并且不能仅仅是一个简单的函数调用,只要父组件(在本例中为 `Home` 组件)是服务器组件。
// ...
import Greet from './greet'
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<Greet />
...
</main>
)
}
如果您想了解更多关于 Rust 和 JavaScript 之间通信的信息,请阅读 Tauri 的 进程间通信 指南。