Tauriの基礎 - 開発環境
概要
Tauriは、RustとWeb技術を組み合わせてデスクトップアプリケーションを構築するための軽量なフレームワークである。
ElectronやNW.jsのような既存のデスクトップアプリケーション開発フレームワークと比較して、Tauriは大幅に小さいバイナリサイズと優れたパフォーマンスを実現している。
これは、ChromiumやNode.jsをバンドルする代わりに、OSが提供するネイティブのWebViewを利用しているからである。
Tauriのアーキテクチャは、バックエンド (コア機能やシステムAPI) にRustを使用し、フロントエンド (ユーザインターフェース) には任意のWebフレームワークを使用できる柔軟な設計になっている。
React、Vue、Svelte、あるいは純粋なHTML / CSS / JavaScript等、開発者が慣れ親しんだ技術を選択することができる。
Tauriで開発されたアプリケーションは、Windows、MacOS、Linuxの各プラットフォーム向けにビルドできる。
また、モバイルプラットフォーム (iOS、Android) のサポートも進行中である。
バックエンドのRustコードは強力な型システムとメモリ安全性を提供し、フロントエンドのReactは豊富なエコシステムと開発者体験を提供する。
この組み合わせにより、安全で高速、かつ保守性の高いデスクトップアプリケーションを開発できる。
依存関係のパッケージのインストール
Tauriがネイティブアプリケーションをビルドするために必要な依存関係をインストールする。
webkit2gtk3はWebViewを表示するためのエンジン、opensslは暗号化通信、他のライブラリはアプリケーションの各種機能やアイコン表示に使用される。
# SUSE sudo zypper install curl wget file webkit2gtk3-devel openssl-devel libappindicator3-devel librsvg-devel
Node.jsのインストール
Reactを動かすためのJavaScript環境が必要である。
最も推奨される方法は、Node Version Manager (nvm) を使用する方法である。
これを使用すると、異なるプロジェクトで異なるNode.jsのバージョンを簡単に切り替えることができる。
Node.jsのインストールは、インストール - Yarn#NordJS のページを参照すること。
Tauri CLIのインストール
Tauriのコマンドラインツールをインストールする。
これには2つの方法が存在するが、推奨される方法は npm を使用する方法である。
# ローカルにインストールする場合 npm install @tauri-apps/cli # グローバルにインストールする場合 npm install -g @tauri-apps/cli # Rustのパッケージマネージャであるcargoを使用する場合 cargo install tauri-cli
インストールが完了した後、動作確認をする。
npm exec tauri --version
プロジェクトの作成
任意のディレクトリに移動して、以下に示すコマンドを実行する。
npm create tauri-app@latest
- プロジェクト名
- 任意の名前 (例: my-tauri-app)
- パッケージマネージャ
- npm
- UIフレームワーク
- React
- TypeScriptを使用するかどうか
- TypeScriptを推奨する。
プロジェクトのセットアップが完了した後、自動生成されたプロジェクトディレクトリに移動する。
cd <プロジェクト名>
プロジェクト構造
srcディレクトリにはReactのフロントエンドコード、src-tauriディレクトリにはRustのバックエンドコードが配置される。
index.html : アプリケーションの入口
index.htmlは、Tauriアプリケーション全体の入り口となるHTMLファイルである。
通常のWebサイトと同様、TauriのWebViewが最初に読み込むページとなる。
head タグの中には基本的なメタ情報、body タグの中には div タグが1つだけあり、そこにid="root"のような属性が付いている。
この div タグが、Reactアプリケーション全体が描画される場所になる。
ファイルの最後には script タグがあり、JavaScriptファイル (通常は、src/main.tsxやsrc/main.jsx) を読み込んでいる。
※重要
画面の内容は、全てReactが動的に生成して、このrootのdiv要素の中に挿入していく。
これが、シングルページアプリケーション (SPA) と呼ばれる仕組みの基本である。
tsconfig.json : TypeScriptのメイン設定
TypeScriptコンパイラに対して、「どのようにTypeScriptコードをJavaScriptコードに変換すればよいか」を指示する設定ファイルである。
TypeScriptは、JavaScriptに型の概念を追加した言語で、開発時にはTypeScriptで記述するが、動作させる時にはJavaScriptに変換する必要がある。
この変換ルールがtsconfig.jsonに記述されている。
例えば、以下に示すような設定が含まれている。
- どのバージョンのJavaScriptに変換するか
- どのディレクトリのファイルをコンパイル対象にするか
- strictモード (厳格な型チェック) を有効にするか
Reactを使用する場合は、JSXという特殊な構文をどう扱うかという設定も重要である。
JSXは、JavaScript内でHTMLのような記述ができる構文である。
{
// TypeScriptコンパイラのオプション設定
// これらの設定により、TypeScriptがどのようにコードをJavaScriptに変換するかが決まる
"compilerOptions": {
// コンパイル対象となるJavaScriptのバージョンを指定
// ES2020は2020年に標準化されたECMAScript仕様で、async/awaitやオプショナルチェイニングなどの機能が使える
"target": "ES2020",
// クラスフィールドの定義方法を新しい仕様(defineProperty)を使うように設定
// これにより、クラスのプロパティがより予測可能な動作をする
"useDefineForClassFields": true,
// TypeScriptで使用できるライブラリの型定義を指定
// ES2020: ES2020の標準ライブラリの型定義
// DOM: ブラウザのDOM(document、windowなど)の型定義
// DOM.Iterable: DOMの反復可能なオブジェクト(NodeListなど)の型定義
"lib": ["ES2020", "DOM", "DOM.Iterable"],
// モジュールシステムの形式を指定
// ESNextは最新のECMAScriptモジュール仕様を使用することを意味する(import/export構文)
"module": "ESNext",
// node_modulesの型チェックをスキップして、ビルド速度を向上させる
// サードパーティライブラリの型エラーを無視することで、開発効率を上げる
"skipLibCheck": true,
/* バンドラーモード関連の設定 */
// ViteやWebpackなどのモダンなバンドラーツールと連携するための設定
// モジュールの解決方法を「bundler」に設定
// これにより、バンドラーが独自のモジュール解決ロジックを使うことを前提とした設定になる
"moduleResolution": "bundler",
// .ts拡張子を含むimport文を許可する
// 通常、TypeScriptは拡張子なしでimportするが、バンドラーモードではこれが許可される
"allowImportingTsExtensions": true,
// JSONファイルをモジュールとしてimportできるようにする
// import data from './data.json' のような書き方が可能になる
"resolveJsonModule": true,
// 各ファイルを独立したモジュールとして扱う
// これにより、各ファイルが他のファイルに依存せずにコンパイルされ、Viteなどのツールと相性が良い
"isolatedModules": true,
// JavaScriptファイルを出力しない
// Viteが独自にトランスパイルとバンドルを行うため、TypeScriptコンパイラはファイルを出力する必要がない
"noEmit": true,
// JSX(ReactのHTML風構文)を「react-jsx」形式で変換
// React 17以降の新しいJSX変換方式を使用し、各ファイルで明示的にReactをimportする必要がなくなる
"jsx": "react-jsx",
/* コード品質チェック(Linting)関連の設定 */
// これらの設定により、より厳格な型チェックと潜在的なバグの検出が行われる
// strictモードを有効化
// これにより、すべての厳格な型チェックオプションが一括で有効になる
// (null安全性、暗黙のany型の禁止、thisの型チェックなど)
"strict": true,
// 使用されていないローカル変数がある場合にエラーを出す
// コードの品質を保ち、不要な変数を削除するのに役立つ
"noUnusedLocals": true,
// 使用されていない関数のパラメータがある場合にエラーを出す
// これにより、不要な引数を持つ関数を発見できる
"noUnusedParameters": true,
// switch文でcase句からbreak/returnなしで次のcase句に落ちる(fall through)場合にエラーを出す
// 意図しないバグを防ぐための安全機能
"noFallthroughCasesInSwitch": true
},
// TypeScriptコンパイラが処理対象とするディレクトリを指定
// この場合、srcディレクトリ内のすべてのTypeScriptファイルが対象となる
"include": ["src"],
// プロジェクト参照を設定
// tsconfig.node.jsonを参照することで、ビルドツール用の設定とアプリケーション用の設定を分離している
// これにより、Node.js環境で実行されるコード(vite.config.tsなど)とブラウザで実行されるコードで
// 異なるコンパイル設定を適用できる
"references": [{ "path": "./tsconfig.node.json" }]
}
tsconfig.node.json : ビルドツール用のTypeScript設定
ビルドツール (Vite等) の設定ファイルをTypeScriptで記述する時に使用する設定である。
tsconfig.json および tsconfig.node.json が2つに分割されている理由として、実行環境が違うからである。
tsconfig.jsonはWebViewで動作するための設定、tsconfig.node.jsonはNode.js環境で動作する (ビルドやバンドルの処理を行うツール) ための設定である。
WebView環境 と Node.js環境 では、使用できる機能や推奨される設定が異なるため、設定を分離して管理した方が効率的である。
例えば、vite.config.ts ファイルはNode.js環境で実行される設定ファイルである。
このファイルがTypeScriptで記述されているため、それをコンパイルするための設定がtsconfig.node.jsonに記述されている。
{
// このファイルは、Node.js環境で実行されるビルドツール用のTypeScript設定ファイルです
// 具体的には、vite.config.tsなどの設定ファイルをコンパイルする際に使用されます
"compilerOptions": {
// compositeモードを有効化
// これにより、プロジェクト参照(Project References)機能が使えるようになる
// 大規模なプロジェクトで複数のtsconfig.jsonを連携させる際に必要な設定
// メインのtsconfig.jsonから、このtsconfig.node.jsonを参照できるようになる
"composite": true,
// node_modulesの型チェックをスキップ
// サードパーティライブラリの型定義ファイルをチェックしないことで、コンパイル速度を向上させる
// 開発体験の改善に役立つ設定
"skipLibCheck": true,
// モジュールシステムの形式を指定
// ESNextは最新のECMAScriptモジュール仕様(import/export)を使用する
// Node.jsの最新バージョンではESモジュールがネイティブでサポートされている
"module": "ESNext",
// モジュールの解決方法を「bundler」モードに設定
// Viteのようなモダンなバンドラーツールが使用する独自のモジュール解決ロジックに対応
// これにより、バンドラーが期待する形式でモジュールが解決される
"moduleResolution": "bundler",
// デフォルトエクスポートを持たないモジュールからのデフォルトインポートを許可
// 例えば、CommonJS形式で書かれたライブラリを、ES6のimport文でインポートできるようになる
// import React from 'react' のような書き方が可能になる(Reactはデフォルトエクスポートを持たない)
"allowSyntheticDefaultImports": true
},
// このTypeScript設定ファイルが対象とするファイルを指定
// この設定では、vite.config.tsファイルのみが対象となる
// つまり、このtsconfig.node.jsonは、Viteの設定ファイルをコンパイルするためだけに使われる
// アプリケーションのソースコード(srcディレクトリ)は、メインのtsconfig.jsonで処理される
"include": ["vite.config.ts"]
}
vite.config.ts : Viteの設定ファイル
Viteというビルドツールの設定ファイルである。
Viteは、フロントエンド開発で人気のある開発サーバとビルドツールである。
このファイルには、以下に示す設定が記述されている。
- 開発サーバをどのポートで起動するか
- どのプラグインを使うか
- ビルド時にどのような最適化を行うか
Tauri + Reactのプロジェクトでは、Reactを使用するためのプラグインやTauriとViteを連携させるための設定が含まれている。
Viteでは、開発中にソースコードを変更すると瞬時にアプリケーションに反映される ホットモジュールリプレースメント (HMR) という機能でがある。
これにより、ソースコードを変更するたびに変更した部分だけがリロードされるため、開発効率が大幅に向上する。
src/main.tsx : Reactアプリケーションの起動コード
Reactアプリケーションを実際に起動させるソースコードを記述する。
ReactDOMライブラリを使用して、Appコンポーネントをindex.htmlのroot要素にマウント (描画) している。
このファイルが実行されることにより、Reactアプリケーションが動作する。
また、このファイルでは、アプリケーション全体に影響する初期設定やグローバルなスタイルシートのインポートも行われることがある。
アプリケーションが起動する直後に実行したい処理がある場合は、このファイルに記述する。
src/App.tsx : メインのReactコンポーネント
アプリケーションのメインとなるReactコンポーネントである。
コンポーネントはReactにおける部品のようなもので、画面の一部分や機能をまとめたものである。
Appコンポーネントは、最上位のコンポーネントであり、アプリケーション全体の構造を定義する。
このファイルでは、function App() のような関数定義があり、その中でJSXを使用して画面の構造が記述されている。
初期状態では、Tauriのロゴや簡単なカウンタのボタン等が含まれている。(動作確認のためのサンプルコード)
実際の開発では、App.tsxファイルに全てを記述するのではなく、機能ごとに複数のコンポーネントを作成して、それらをApp.tsxで組み合わせる。
例えば、ヘッダコンポーネント、サイドバーコンポーネント、メインコンテンツコンポーネント等を別々に作成して、Appコンポーネントでそれらを配置する。
src/App.css : Appコンポーネントのスタイル
App.tsxコンポーネントの見た目を定義するCSSファイルである。
App.tsxファイルでは、App.cssをインポートしている。
Reactでは、コンポーネントごとにスタイルシートを分離して管理することが一般的である。
"このスタイルはどのコンポーネントで使われているのか" が明確になり、保守性が上がる。
また、TailwindCSSのようなCSSフレームワークを使用する場合は、このファイルの役割が変わることもある。
src/vite-env.d.ts : Viteの型定義ファイル
TypeScriptの型定義ファイルである。
ファイル名の末尾にある「.d.ts」というのは、declaration type scriptの略で、型の宣言のみを記述するファイル という意味である。
Viteが提供する型定義を参照する指示が記述されている。
これにより、Vite特有の機能、環境変数の読み込み、モジュールのインポート等に使用する時に、TypeScriptのエディタ上で補完および型チェックができる。
このファイルは、基本的に編集する必要はない。プロジェクト作成時に自動生成され、そのまま使用し続けるものである。
ただし、Vite以外の特殊な型定義を追加する場合は、このファイルを編集することもある。
IDE
IDEA Ultimate
IDEA Ultimateでは、プロジェクトのルートディレクトリを開く。
Tauriプロジェクトは、2つの異なるプロジェクトを組み合わせた構造である。
2つを統合的に管理するための設定ファイルや情報が、全てルートディレクトリに存在する。
- Reactを使用したフロントエンドのプロジェクト
- Rustで記述したバックエンドのプロジェクト
ルートディレクトリには、package.jsonというNode.jsプロジェクトの設定ファイルが存在する。
IDEA Ultimateはこれらのファイルを発見した時、Node.jsのプロジェクトと理解して適切なJavaScriptやReactの開発サポート機能を有効にする。
同時に、src-tauriディレクトリの中にあるCargo.toml (Rustプロジェクトの設定ファイル) も認識して、Rustのソースコードサポートも提供する。
ルートディレクトリを開く時、IDEA Ultimateは次のように動作する。
- まず、プロジェクトを開いた直後、IDEA Ultimateは自動的に依存関係を解析する。
- 解析が完了した後、srcディレクトリ内のReactコンポーネントを編集する場合は、Reactの関数やフックの補完が利用できるようになる。
- 同様に、src-tauriディレクトリのRustコードを編集する場合は、Rustの型情報や関数の補完が利用できるようになる。
IDEA UltimateのみでRust開発を行う場合は、Rustプラグイン (Rust) のインストールが必要である。
プラグインのインストール手順は、以下の通りである。
- [ファイル]メインメニュー - [設定]を選択する。
- 左側のメニューから[Plugins]を選択する。
- 上部の検索バーに Rust と入力する。
- 検索結果に表示されるRustプラグインをインストールする。
- インストール後、IDEを再起動する。
Rustプラグインをインストールすると、以下に示す機能が利用可能になる。
- シンタックスハイライト
- コード補完機能
- Cargoコマンドの統合により、IDE内から直接ビルドや実行が可能になる。
任意でTauriプラグインもインストール可能である。
このプラグインは、Tauriのコマンド定義やコンフィグファイルの編集をサポートする。
RustRover
RustRoverでは、プロジェクトのルートディレクトリを開く。
RustRoverは、JetBrainsが提供するRust専用の統合開発環境である。
IDEA Ultimateと同じJetBrainsファミリーの製品だが、Rustに特化して設計されている。
ルートディレクトリを開くと、RustRoverはsrc-tauriディレクトリ内のCargo.tomlを発見し、そのディレクトリをRustプロジェクトの中心として認識する。
Rustのソースコードに対しては、IDEA Ultimateよりもさらに高度な解析機能が提供される。
マクロの展開結果の表示、詳細な型推論、Cargoコマンドの統合実行環境等、Rust開発に特化した機能が豊富に用意されている。
RustRoverはReactやTypeScriptのサポートについては、IDEA Ultimateほど充実しておらず、
基本的なJavaScriptやTypeScriptの編集はできるが、Reactコンポーネントの補完やリファクタリング機能等は限定的である。
実務では、以下に示すような使い分けが推奨される。
フロントエンドとバックエンドの両方を頻繁に行き来する場合は、IDEA Ultimateを使用する。
これは、1つのIDEウィンドウで両方のコードを快適に編集できるためである。
しかし、Rustのソースコードを記述する時間が長い場合や複雑なRustのソースコードを扱う場合は、RustRoverを使用する。