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
的行為,以產生一個 out/
資料夾,其中包含應用程式的 HTML/CSS/JS 資源,而不是將它們寫入特定於 Next.js 執行時期的 .next/
目錄。
還有更多可能的組態選項,因此請務必閱讀上文提到的 靜態輸出 文件,並根據專案需求調整組態檔。
建立 Rust 專案
每個 Tauri 應用程式的核心都是一個 Rust 二進位檔,它透過稱為 tauri
的 Rust crate 來管理視窗、網頁檢視和對作業系統的呼叫。這個專案是由 Rust 的官方套件管理員和通用建置工具 Cargo 管理的。
我們的 Tauri CLI 在幕後使用 Cargo,因此您很少需要直接與它互動。Cargo 有更多未透過我們的 CLI 公開的有用功能,例如測試、程式碼檢查和格式化,因此請參閱他們的 官方文件 以取得更多資訊。
如果您尚未安裝 Tauri CLI,可以使用以下命令之一進行安裝。不確定要使用哪一個嗎?請查看 常見問題解答條目。
- npm
- Yarn
- pnpm
- Bun
- Cargo
npm install --save-dev @tauri-apps/cli
"scripts": {
"tauri": "tauri"
}
yarn add -D @tauri-apps/cli
pnpm add -D @tauri-apps/cli
bun add -D @tauri-apps/cli
cargo install tauri-cli
若要建立預先組態為使用 Tauri 的最小 Rust 專案,請開啟終端機並執行以下命令
- npm
- Yarn
- pnpm
- Bun
- Cargo
npm run tauri init
yarn tauri init
pnpm tauri init
bunx tauri init
cargo tauri init
它會引導您完成一系列問題
- 您的應用程式名稱為何?
這將會是您最終套件的名稱,以及作業系統會如何稱呼您的應用程式。您可以在這裡使用任何您想要的應用程式名稱。 - 視窗標題應該是什麼?
這將會是預設主視窗的標題。您可以在這裡使用任何您想要的標題。 - 您的網頁資源(HTML/CSS/JS)相對於將建立的
<current dir>/src-tauri/tauri.conf.json
檔案位於何處?
這是 Tauri 在為生產環境建置時,將會從中載入您的前端資源的路徑。請使用../out
作為此值。 - 您的開發伺服器網址為何?
這可以是 URL 或檔案路徑,Tauri 將在開發期間載入。請使用http://localhost:3000
作為此值。 - 您的前端開發指令為何?
這是用來啟動您的前端開發伺服器的指令。請使用npm run dev
作為此值(請務必調整為使用您選擇的套件管理員)。 - 您的前端建置指令為何?
這是用來建置您的前端檔案的指令。請使用npm run build
作為此值(請務必調整為使用您選擇的套件管理員)。
如果您熟悉 Rust,您會注意到 tauri init
的外觀和運作方式與 cargo init
非常相似。如果您偏好完全手動設定,您可以直接使用 cargo init
並加入必要的 Tauri 相依性套件。
tauri init
指令會產生一個名為 src-tauri
的資料夾。Tauri 應用程式會將所有核心相關檔案放置到此資料夾中,這是一個慣例。讓我們快速瀏覽此資料夾的內容
Cargo.toml
Cargo 的清單檔案。您可以宣告應用程式所依賴的 Rust 板條箱、應用程式的元資料,以及更多內容。有關完整參考,請參閱 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
函式是進入點,也是程式碼執行時第一個被呼叫的函式。icons
您很可能想要為應用程式設定一個時髦的圖示!為了讓您快速上手,我們包含了一組預設圖示。在發佈應用程式之前,您應該將這些圖示換掉。在 Tauri 的 圖示功能指南 中,進一步了解各種圖示格式。
現在我們已經建立好前端架構並初始化 Rust 專案,您幾乎可以執行應用程式了。您的 tauri.conf.json
檔案應該類似於以下內容
{
"build": {
"beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev",
"devPath": "http://localhost: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
yarn add @tauri-apps/api
pnpm add @tauri-apps/api
bun add @tauri-apps/api
需要注意的一件重要事情是,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 跨程序通訊指南。