Rust + Tauri 開發一個自動生成申論的桌面應用

前端開發桌面應用,第一反應肯定是 Electron

但 Electron 有一個衆所周知的問題:每一個應用都會打包一個 chromium。如果電腦上安裝了10個 Electron 應用,就會安裝10個 chromium

而 Tauri 使用 WebView 作爲 GUI 方案,不會打包在應用內,而是檢查系統是否有預裝 WebView,從而避免多個應用重複安裝的問題。

 

一、創建項目

Tauri 使用了 Rust,所以需要提前安裝 Rust 的相關環境,可以參考《Rust 走馬觀花(一)—— 從安裝到編譯》或者官方文檔《預先準備》

Tauri 桌面應用由前端應用和後端應用組成,前端應用可以是任意一個 web 項目,本文將使用 vite + react + ts 構建

yarn create vite my-tauri-app --template react-ts

然後安裝 tarui-cli,並創建 Rust 項目

cargo install tauri-cli
cargo tauri init

安裝完成後會在原本的目錄中新增一個 src-tauri 目錄,這就是 tauri 生成的 rust 應用,也就是我們桌面應用的後端部分

安裝過程會有一些配置項,可以參考截圖輸入。即使輸錯了也沒問題,創建項目後可以在 tauri.conf.json 中修改配置

注意:這裏的 devPath 必須爲有效地址,否則無法正確啓動開發模式

到此爲止,一個 Tarui 項目的基本結構就已經搭建好了,可以使用 cargo tauri dev 命令運行項目

開發完成後,可以通過 cargo tauri build 命令構建,不過在構建之前,需要修改 tauri.conf.json 中的 identifier 字段,也就是當前應用的 id,需要保證唯一性

如需構建 windows 應用,還得在配置文件中添加 wix 配置項

{
  "tauri": {
    "bundle": {
     "identifier": "com.tauri.xxxxxxxx", // 保證唯一
      "windows": {
        "wix": {
          "language": "zh-CN"
        }
      }
    }
  }
}

 

二、功能開發(JS版本)

接下來完成應用的業務功能,也就是一鍵生成一篇申論

具體功能是模仿申論生成器,源碼來自 GitHub: https://github.com/Uahh/slscq

過程就不再贅述,可以按照 web 應用的形式開發,然後打包爲桌面應用。也就是僅用 Tauri 做一個桌面應用的殼

 


 這時候應用的圖標還是 Tauri 的默認圖標,可以先設計一個自己的圖標 (1024 x 1024px, png, 透明背景),然後重命名爲 app-icon.png,放到 src-tauri 目錄下

然後在 src-tauri 目錄下啓動終端,執行命令 cargo tauri icon,tauri 就會在 icons 目錄下自動生成一套圖標

最後在 tauri.conf.json 修改應用標題(如果創建項目的時候已配置好則忽略這一步)

這樣一個相對完整的桌面應用的就開發完成

但就像上文所說,這樣的應用還只是一個套殼的 web 應用,沒有用到桌面應用的特性,比如文件讀寫,也沒用到 Rust,接下來就將逐步完善

 

三、文件導出

文章生產之後,順利成章的就會有“導出”的需求。可以通過文件系統 fs 來實現該功能

文件系統的讀寫功能默認是關閉的,需要在配置文件 tauri.conf.json 中的 allowlist 開啓

{
  "tauri": {
    "allowlist": {
      "fs": {
        "scope": ["*"],
        "all": true
      }
    }
  }
}

這裏最關鍵的是 scope 字段(必填),用於限制應用可訪問的本地文件目錄。我這裏設置爲了通配符,需要根據實際需求調整

保存文件的時候需要文件路徑,常見的交互是彈出 dialog 讓用戶選擇文件的保存歷經,這就需要用到 dialog 組件,所以最終的 allowlist 爲:

{
  "tauri": {
    "allowlist": {
      "dialog": {
        "all": true
      },
      "fs": {
        "scope": ["*"],
        "all": true
      }
    }
  }
}

fs 和 dialog 的能力是 Rust 提供的,在前端應用使用 Rust 還需要引入另外的依賴包 @tauri-apps/api

yarn add @tauri-apps/api

最終下載文件的完整邏輯爲

import { save } from '@tauri-apps/api/dialog';
import { writeTextFile } from '@tauri-apps/api/fs';

const [content, setContent] = useState<{
  title: string;
  plaintext: string;
  html: string;
}>();

const handleDownload = async () => {
  if (!content) return;
  const filePath = await save({
    defaultPath: `${content.title}.txt`,
  });
  if (!filePath) return;
  writeTextFile(filePath, content.plaintext);
}

 

四、使用 Rust 改造

目前應用的核心邏輯還是用 js 實現的,接下來可以改造爲 rust,畢竟 rust 的性能更好

改造的過程不多展開,假如最終在 main.rs 中實現了一個函數 generator, 直接返回完整內容

該函數需要以指令的形式暴露給前端應用,所以需要加上 #[tauri::command] 的宏

最終還需要在 main 函數中通過 invoke_handler 暴露該指令

.invoke_handler(tauri::generate_handler![ fn1, fn2, fn3 ])

然後在前端應用中,通過 tauri 提供的 invoke 方法使用指令

import { invoke } from '@tauri-apps/api';

const handleSubmit = async () =>const res = await invoke<string>('generator', { 
    // 對應 rust 函數中定義的參數名
    theme: '文章主題',
    size: 100, 
  });
  console.log('handleSubmit===>', res);
}

調用的時候需要注意以下幾點:

1. invoke 是一個異步函數,返回 Promise

2. invoke 的第一個參數是 rust 函數名,第二個參數是一個對象,需要按照 rust 中定義的參數名傳參 

 

五、跨平臺編譯

本小節內容參考自官網《跨平臺編譯》

Tauri 的編譯十分依賴本地環境,所以無法在本地實現跨平臺編譯,更好的方案是使用 GitHub Actions

首先需要創建一個 GitHub 倉庫,然後創建一個工作流

 

可以使用 Tauri 提供的工作流示例,該腳本會在推送滿足條件的 tags 時執行

工作流開始運行之後,可以在 Actions 中查看進度

工作流執行完成後,會創建一個草稿狀態的 release,並攜帶構建產物

可以下載這些安裝包,在各個環境驗證一下。驗證無誤,可以編輯該 release 併發布

至此一個完整的 Tauri APP 構建流程就結束了~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章