Tauri + SvelteでHello World作成
Tags: svelte, tauri
Published: 2022-04-03 08:40:47

[Tauri](https://tauri.studio/)と[Svelte](https://svelte.dev/)でHello Worldアプリを作ってみる。

## 環境

- OS : macOS Monterey (12.3.1)
- XCode : 13.1
- Rust : 1.59.0
- Node : 17.8.0

```bash
% uname -v
Darwin Kernel Version 21.4.0: Fri Mar 18 00:47:26 PDT 2022; root:xnu-8020.101.4~15/RELEASE_ARM64_T8101
% xcode-select -p
/Applications/Xcode-13.1.app/Contents/Developer
% rustc --version
rustc 1.59.0
% node --version
v17.8.0
% npm --version
8.5.5
```

## Svelteプロジェクト作成

1. [https://github.com/sveltejs/template](https://github.com/sveltejs/template) を参照してSvelteセットアップ

```bash
% mkdir tauri-helloworld
% cd tauri-helloworld
% npm i -D degit
% npx degit sveltejs/template --force
% node scripts/setupTypeScript.js <-- Typescript対応
```

1. Svelteプロジェク動作確認

```json
% npm i
% npm run dev

> svelte-app@1.0.0 dev
> rollup -c -w

rollup v2.70.1
bundles src/main.ts → public/build/bundle.js...
LiveReload enabled
created public/build/bundle.js in 571ms

[2022-04-03 16:05:28] waiting for changes...

> svelte-app@1.0.0 start
> sirv public --no-clear "--dev"

  Your application is ready~! 🚀

  - Local:      http://localhost:8080
  - Network:    Add `--host` to expose

────────────────── LOGS ──────────────────
```

## Tauri プロジェクト作成

1. Project directoryを作成して `@tauri-apps/cli` と `@tauri-apps/api` をインストール

```bash
% npm i -D @tauri-apps/cli @tauri-apps/api
```

1. Tauriプロジェクを初期化
    1. Web Assets Location : FrontendのProductionモードでビルド先を指定。 `../public`
    2. The URL of Dev Server : Frontend開発時に使うURL指定。 `http://localhost:8080`

```bash
% npx tauri init
✔ What is your app name? · svelte-app
✔ What should the window title be? · Tauri Hello World
✔ Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that will be created? · ../public
✔ What is the url of your dev server? · http://localhost:8080
```

1.  `src-tauri/tauri.conf.json` 編集
    1. `build.beforeDevCommand` : `npm run dev`
    2. `build.beforeBuildCommand` : `npm run build`

```diff
{
  "package": {
    "productName": "svelte-app",
    "version": "0.1.0"
  },
  "build": {
    "distDir": "../public",
    "devPath": "http://localhost:8080",
-    "beforeDevCommand": "",
-    "beforeBuildCommand": ""
+    "beforeDevCommand": "npm run dev",
+    "beforeBuildCommand": "npm run build"
  },
  "tauri": {
    "bundle": {
      "active": true,
      "targets": "all",
      "identifier": "com.tauri.dev",
      "icon": [
        "icons/32x32.png",
        "icons/128x128.png",
        "icons/128x128@2x.png",
        "icons/icon.icns",
        "icons/icon.ico"
      ],
      "resources": [],
      "externalBin": [],
      "copyright": "",
      "category": "DeveloperTool",
      "shortDescription": "",
      "longDescription": "",
      "deb": {
        "depends": [],
        "useBootstrapper": false
      },
      "macOS": {
        "frameworks": [],
        "useBootstrapper": false,
        "exceptionDomain": "",
        "signingIdentity": null,
        "providerShortName": null,
        "entitlements": null
      },
      "windows": {
        "certificateThumbprint": null,
        "digestAlgorithm": "sha256",
        "timestampUrl": ""
      }
    },
    "updater": {
      "active": false
    },
    "allowlist": {
      "all": true
    },
    "windows": [
      {
        "title": "Tauri Hello World",
        "width": 800,
        "height": 600,
        "resizable": true,
        "fullscreen": false
      }
    ],
    "security": {
      "csp": null
    }
  }
}
```

1. Tauriアプリ動作確認

```json
% npx tauri dev
```

![run hello world](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/typvc7ipxbhwkptezh35.png)

1. Tauri Info

```bash
% npx tauri info

Environment
  › OS: Mac OS 12.3.1 X64
  › Node.js: 17.8.0
  › npm: 8.5.5
  › pnpm: Not installed!
  › yarn: Not installed!
  › rustup: Not installed!
  › rustc: 1.59.0
  › cargo: 1.59.0
  › Rust toolchain: 

Packages
  › @tauri-apps/cli [NPM]: 1.0.0-rc.7(outdated, latest: 1.0.0-rc.8)
  › @tauri-apps/api [NPM]: 1.0.0-rc.3(outdated, latest: 1.0.0-rc.3)
  › tauri [RUST]: 1.0.0-rc.6,
  › tauri-build [RUST]: 1.0.0-rc.5,
  › tao [RUST]: 0.7.0,
  › wry [RUST]: 0.14.0,

App
  › build-type: bundle
  › CSP: unset
  › distDir: ../public
  › devPath: http://localhost:8080/
  › framework: Svelte
  › bundler: Rollup

App directory structure
  ├─ node_modules
  ├─ public
  ├─ src-tauri
  ├─ .git
  ├─ .vscode
  └─ src
```

## Rust Commandを試してみる

1. `hello_command` 作成
```diff
// src-tauri/src/main.rs

fn main() {
  tauri::Builder::default()
+   .invoke_handler(tauri::generate_handler![hello_command])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

+#[tauri::command]
+fn hello_command(name: String) -> String {
+  return format!("Hello {}!", name).into()
+}
```
 
1. Svelteの方から `hello_command` をinvoke
```diff
// src/App.svelte
 <script lang="ts">
+       import { invoke } from "@tauri-apps/api";
+
        export let name: string;
+       let messagePromise = invoke("hello_command", { name });
 </script>

 <main>
-       <h1>Hello {name}!</h1>
+       {#await messagePromise}
+               <h1>Loading.invoke.</h1>
+       {:then message}
+               <h1>{message}</h1>
+       {:catch err}
+               <h1>{err}</h1>
+       {/await}
        <p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
 </main>
```
 
```diff
// src/main.ts

 const app = new App({
        target: document.body,
        props: {
-               name: 'world'
+               name: 'Tauri'
        }
 });
```

![run hello tauri](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0haw15ct8dpzutd51wz.png)

## Template化したもの

[https://github.com/dannygim/template-tauri-svelte](https://github.com/dannygim/template-tauri-svelte)

```bash
npx degit dannygim/template-tauri-svelte tauri-svelte-app
```