T-CREATOR

Tauriのプロジェクト構成と各ディレクトリの役割

Tauriのプロジェクト構成と各ディレクトリの役割

Tauri を使ったデスクトップアプリ開発を始めたとき、「どのファイルがどこにあるのか分からない」「エラーが出ても原因が特定できない」という経験はありませんか?

実は、Tauri のプロジェクト構成を正しく理解することで、開発効率が格段に向上し、トラブルシューティングも驚くほどスムーズになります。この記事では、実際の開発現場でよく遭遇する問題とその解決策を交えながら、Tauri プロジェクト構成の全体像を分かりやすく解説いたします。

Tauri プロジェクト構成の基礎知識

構成要素の全体像

Tauri プロジェクトは、Web 技術と Rust を組み合わせた独特な構成を持っています。一見複雑に見えますが、実際は明確な役割分担があります。

基本的な Tauri プロジェクトの構成は以下のようになります:

typescriptmy-tauri-app/
├── src/                    # フロントエンド(Web)部分
│   ├── main.ts            # エントリーポイント
│   ├── App.vue            # メインコンポーネント
│   └── components/        # Webコンポーネント
├── src-tauri/             # バックエンド(Rust)部分
│   ├── src/               # Rustソースコード
│   ├── target/            # Rustビルド成果物
│   ├── icons/             # アプリケーションアイコン
│   ├── Cargo.toml         # Rust依存関係
│   └── tauri.conf.json    # Tauri設定
├── public/                # 静的ファイル
├── package.json           # Node.js依存関係
└── yarn.lock              # Yarn依存関係ロック

この構成で最も重要なのは、フロントエンド(Web)とバックエンド(Rust)が明確に分離されているという点です。

各要素の依存関係

Tauri アプリケーションの依存関係は、以下のような流れで成り立っています:

mermaidgraph TD
    A[package.json] --> B[Web依存関係]
    C[src-tauri/Cargo.toml] --> D[Rust依存関係]
    E[tauri.conf.json] --> F[アプリ設定]
    B --> G[フロントエンドビルド]
    D --> H[バックエンドビルド]
    G --> I[最終アプリケーション]
    H --> I
    F --> I

この依存関係を理解することで、「なぜエラーが発生するのか」「どのファイルを修正すればよいのか」が明確になります。

必須ディレクトリとファイル

絶対に必要な構成要素

Tauri プロジェクトで絶対に必要な要素は以下の通りです:

1. src-tauri ディレクトリ

rust// src-tauri/src/main.rs
#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

fn main() {
    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

このファイルが存在しないと、以下のエラーが発生します:

javascriptError: Could not find `src-tauri/src/main.rs`
failed to run custom build command for `tauri-build v1.5.0`

2. tauri.conf.json 設定ファイル

json{
  "build": {
    "beforeBuildCommand": "yarn build",
    "beforeDevCommand": "yarn dev",
    "devPath": "http://localhost:3000",
    "distDir": "../dist"
  },
  "package": {
    "productName": "my-tauri-app",
    "version": "0.1.0"
  },
  "tauri": {
    "allowlist": {
      "all": false
    },
    "bundle": {
      "active": true,
      "identifier": "com.example.app",
      "targets": "all"
    }
  }
}

この設定ファイルがないと、以下のエラーが表示されます:

javascriptError: Could not find `tauri.conf.json` or `Tauri.toml` in the specified directory

3. Cargo.toml ファイル

toml[package]
name = "my-tauri-app"
version = "0.1.0"
edition = "2021"

[build-dependencies]
tauri-build = { version = "1.5", features = [] }

[dependencies]
tauri = { version = "1.5", features = ["api-all"] }

オプションだが推奨される構成要素

開発効率を大幅に向上させる推奨要素をご紹介します:

1. TypeScript 設定

json// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

2. 開発用スクリプト

json// package.json
{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "tauri": "tauri"
  }
}

これらの設定により、開発体験が劇的に改善されます。

よくある構成ミスと対策

パス設定の間違い

最も頻発する問題の一つがパス設定の間違いです。

問題:devPath設定ミス

json// 間違った設定
{
  "build": {
    "devPath": "http://localhost:3001", // 実際は3000で動作
    "distDir": "../dist"
  }
}

このエラーが発生すると、以下のメッセージが表示されます:

vbnetError: failed to connect to development server at http://localhost:3001
Connection refused (os error 61)

解決策:

開発サーバーの実際のポート番号を確認し、正しく設定してください:

json// 正しい設定
{
  "build": {
    "devPath": "http://localhost:3000",
    "distDir": "../dist"
  }
}

設定ファイルの配置ミス

問題:tauri.conf.json の配置場所

perl# 間違った配置
my-tauri-app/
├── src/
├── tauri.conf.json  # ルートディレクトリに配置(間違い)
└── src-tauri/
    └── Cargo.toml

この場合、以下のエラーが発生します:

javascriptError: Could not find `tauri.conf.json` in `src-tauri` directory

解決策:

css# 正しい配置
my-tauri-app/
├── src/
└── src-tauri/
    ├── tauri.conf.json  # src-tauriディレクトリ内に配置
    └── Cargo.toml

依存関係の問題

問題:Rust ツールチェーンの不整合

開発中によく遭遇するエラーの一つが、Rust ツールチェーンのバージョン不整合です:

vbnetError: could not compile `tauri-build` due to 1 previous error
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual Studio Build Tools"

解決策:

Windows 環境の場合:

bash# Visual Studio Build Toolsをインストール
# https://visualstudio.microsoft.com/visual-cpp-build-tools/

# Rustツールチェーンを更新
rustup update

macOS 環境の場合:

bash# Xcode Command Line Toolsをインストール
xcode-select --install

# Rustツールチェーンを更新
rustup update

効率的な構成管理方法

開発効率を上げる構成テクニック

1. 環境別設定の分離

開発環境と本番環境で異なる設定を使用したい場合、以下のような構成が効果的です:

json// src-tauri/tauri.conf.json
{
  "build": {
    "beforeBuildCommand": "yarn build",
    "beforeDevCommand": "yarn dev",
    "devPath": "http://localhost:3000",
    "distDir": "../dist"
  },
  "tauri": {
    "allowlist": {
      "all": false,
      "fs": {
        "all": false,
        "readFile": true,
        "writeFile": true,
        "readDir": true,
        "copyFile": true,
        "createDir": true,
        "removeDir": true,
        "removeFile": true,
        "renameFile": true
      }
    }
  }
}

2. デバッグ用設定の活用

開発中のデバッグを効率化するための設定:

rust// src-tauri/src/main.rs
#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            #[cfg(debug_assertions)]
            {
                let window = app.get_window("main").unwrap();
                window.open_devtools();
            }
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

この設定により、デバッグモードでは自動的に開発者ツールが開くようになります。

メンテナンス性を考慮した構成

1. 機能別ディレクトリ分割

typescriptsrc/
├── components/           # 再利用可能なコンポーネント
│   ├── common/          # 共通コンポーネント
│   ├── forms/           # フォーム関連
│   └── layout/          # レイアウト関連
├── pages/               # ページコンポーネント
├── hooks/               # カスタムフック
├── utils/               # ユーティリティ関数
├── types/               # TypeScript型定義
└── store/               # 状態管理

2. 設定ファイルの分割

typescript// src/config/app.ts
export const appConfig = {
  development: {
    apiUrl: 'http://localhost:8080',
    debug: true,
  },
  production: {
    apiUrl: 'https://api.example.com',
    debug: false,
  },
};

チーム開発での構成管理

1. EditorConfig 設定

ini# .editorconfig
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.rs]
indent_size = 4

2. 開発環境の統一

json// .vscode/settings.json
{
  "rust-analyzer.checkOnSave.command": "clippy",
  "rust-analyzer.cargo.features": ["dev"],
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}

具体例

正しい構成例

実際の開発現場で推奨される、メンテナンス性の高い構成例をご紹介します:

csharpmy-tauri-app/
├── .vscode/                 # VSCode設定
│   ├── settings.json
│   └── extensions.json
├── src/                     # フロントエンド
│   ├── components/
│   │   ├── Header.vue
│   │   └── Sidebar.vue
│   ├── pages/
│   │   ├── Home.vue
│   │   └── Settings.vue
│   ├── store/
│   │   └── index.ts
│   ├── types/
│   │   └── api.ts
│   └── main.ts
├── src-tauri/              # バックエンド
│   ├── src/
│   │   ├── commands/       # Tauriコマンド
│   │   │   ├── file.rs
│   │   │   └── mod.rs
│   │   ├── utils/          # ユーティリティ
│   │   │   └── mod.rs
│   │   └── main.rs
│   ├── icons/
│   │   ├── 32x32.png
│   │   ├── 128x128.png
│   │   └── icon.ico
│   ├── Cargo.toml
│   └── tauri.conf.json
├── public/                 # 静的ファイル
├── package.json
├── yarn.lock
├── .gitignore
└── README.md

コマンドファイルの実装例

rust// src-tauri/src/commands/file.rs
use tauri::command;
use std::fs;

#[command]
pub fn read_file(path: String) -> Result<String, String> {
    match fs::read_to_string(path) {
        Ok(content) => Ok(content),
        Err(e) => Err(format!("Failed to read file: {}", e))
    }
}

#[command]
pub fn write_file(path: String, content: String) -> Result<(), String> {
    match fs::write(path, content) {
        Ok(_) => Ok(()),
        Err(e) => Err(format!("Failed to write file: {}", e))
    }
}

メインファイルでの登録

rust// src-tauri/src/main.rs
mod commands;

use commands::file::{read_file, write_file};

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

問題のある構成例とその修正

問題例:設定の分散

bash# 問題のある構成
my-tauri-app/
├── config.json           # 設定ファイルが分散
├── src/
│   ├── app-config.ts     # 設定ファイルが分散
│   └── main.ts
├── src-tauri/
│   ├── tauri.conf.json   # 設定ファイルが分散
│   └── app.config.json   # 設定ファイルが分散
└── .env                  # 環境変数も分散

修正後の構成

bash# 修正後の構成
my-tauri-app/
├── src/
│   ├── config/           # 設定を一箇所に集約
│   │   ├── app.ts
│   │   ├── api.ts
│   │   └── index.ts
│   └── main.ts
├── src-tauri/
│   ├── tauri.conf.json   # Tauri固有の設定のみ
│   └── src/main.rs
└── .env                  # 環境変数(最小限)

設定の集約化

typescript// src/config/index.ts
export const config = {
  app: {
    name: 'My Tauri App',
    version: '1.0.0',
  },
  api: {
    baseUrl:
      process.env.NODE_ENV === 'development'
        ? 'http://localhost:8080'
        : 'https://api.example.com',
  },
  features: {
    fileAccess: true,
    notifications: true,
  },
};

この構成により、設定の管理が一元化され、メンテナンス性が大幅に向上します。

まとめ

Tauri プロジェクトの構成を理解することは、単なる技術的な知識以上の価値があります。

正しい構成を理解することで得られるメリット:

メリット具体的な効果
開発効率の向上エラーの原因特定が素早くできる
メンテナンス性の向上機能追加・修正がスムーズになる
チーム開発の円滑化他のメンバーがコードを理解しやすくなる
トラブルシューティングの迅速化問題の発生箇所が特定しやすくなる

最も重要なのは、**「なぜそのような構成になっているのか」**を理解することです。単にファイルの配置を覚えるだけでなく、それぞれの役割と相互関係を把握することで、より柔軟で効率的な開発が可能になります。

Tauri を使った開発で困ったときは、まず構成を見直してみてください。多くの問題は、適切な構成により解決できることが多いものです。

開発者として成長するためには、このような基礎的な構成理解が不可欠です。今回解説した内容を参考に、ぜひ実際のプロジェクトで試してみてください。きっと開発体験が大きく変わることを実感していただけるでしょう。

関連リンク