Tauri プロジェクトのディレクトリ構成

create-tauri-app が作るファイルを「編集する・触らない・生成物」に分けて役割を示す。main.rs と lib.rs の分担、capabilities の読み込み、gen/ と target/ の扱いも整理する。

環境構築 対象: Tauri 2.x 更新日: 読了目安: 約8分 env-008
目次
  1. 前提条件
  2. 1. 全体像と「触ってよいか」
  3. 2. フロントエンド側(プロジェクト直下)
  4. 3. Rust 側(src-tauri/)
  5. main.rs は触らず、lib.rs に書く
  6. そのほかのファイル
  7. 4. 生成物のフォルダ(gen/ と target/)
  8. 動作確認
  9. よくあるエラーと対処法
  10. OS ごとの違いと注意点
  11. 関連レシピ

create-tauri-app で作ったプロジェクトは、直下が普通の Vite プロジェクト(フロントエンド)、src-tauri/ が Rust のプロジェクトという 2 階建てです。日常的に編集するのは一部で、残りは「たまに変える」「触らない」「生成物」のどれかです。この区別がないと、生成物を編集して変更が消えたり、数 GB ある target/ をコミットしかけたりします。vanilla-ts テンプレートを例に整理します。

前提条件

npm create tauri-app@latest でプロジェクトを作り、npm install まで済ませた状態を想定します(Tauri プロジェクトを作成する)。React や Vue のテンプレートでも、違うのはフロントエンド側だけです。Cargo.lock、src-tauri/gen/、src-tauri/target/ は最初の npm run tauri dev の後に現れます。

1. 全体像と「触ってよいか」

my-app/
├── index.html               編集する  WebView が最初に読むページ
├── src/                     編集する  main.ts・styles.css・assets/
├── package.json             編集する  npm スクリプトと @tauri-apps/* の依存
├── package-lock.json        触らない  コミットする
├── vite.config.ts           たまに    ポート 1420 の固定など Tauri 向けの設定
├── tsconfig.json            たまに
├── .vscode/extensions.json  たまに    推奨する VS Code 拡張の一覧
├── .gitignore
├── node_modules/            生成物    npm install
├── dist/                    生成物    npm run build の出力
└── src-tauri/
    ├── tauri.conf.json      編集する  アプリの設定
    ├── Cargo.toml           編集する  Rust の依存クレート
    ├── Cargo.lock           触らない  コミットする
    ├── build.rs             触らない
    ├── capabilities/        編集する  default.json などの権限
    ├── icons/               差し替え  tauri icon で一括生成
    ├── src/main.rs          触らない
    ├── src/lib.rs           編集する  Rust のコードはここに書く
    ├── .gitignore                     /target/ と /gen/schemas を除外
    ├── gen/schemas/         生成物    ビルドのたびに作り直される
    └── target/              生成物    Rust のビルド出力

境界は「src/ を変えると Vite が画面を差し替え、src-tauri/ を変えると tauri dev が Rust を再ビルドしてアプリを再起動する」です(開発サーバーの起動とデバッグ)。vite.config.ts が src-tauri/ を Vite の監視から外しているのはこのためで、消すと Vite が target/ の大量のファイルまで監視して重くなります。

2. フロントエンド側(プロジェクト直下)

  • index.html と src/: 普通の Web ページと同じです。ページの <title> はウィンドウのタイトルには自動で反映されません。
  • package.json: "tauri": "tauri" のスクリプトがあるので npm run tauri dev で CLI を呼べます。JS の API(@tauri-apps/api、@tauri-apps/plugin-*)は dependencies、CLI は devDependencies に入ります。
  • dist/: tauri build の最初に npm run build が作り、中身は実行ファイルに埋め込まれます。別に配る必要はなく、tauri dev では使いません。場所は frontendDist で決まります(tauri.conf.json の基本設定)。

3. Rust 側(src-tauri/)

main.rs は触らず、lib.rs に書く

main.rs はデスクトップ用の入口で、lib.rs の run() を呼ぶだけです。

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

fn main() {
    my_app_lib::run()
}

モバイル版はアプリをライブラリとしてビルドするので、コマンドやプラグインの登録は共通の lib.rs に書きます。2 行目は Windows のリリースビルドで黒いコンソール画面が開くのを防ぐ設定なので消しません。my_app_lib は Cargo.toml の [lib] name と対応します(Cargo.toml で Rust のパッケージを管理する)。lib.rs が長くなったら src-tauri/src/commands.rs などに分け、lib.rs に mod commands; と書いて commands::greet の形で登録します。

そのほかのファイル

ファイル役割と扱い
tauri.conf.jsonアプリの設定。CLI はこのファイルを目印に Rust 側のフォルダを探す
capabilities/権限。中のファイルは名前を問わずすべて読み込まれ、platforms で OS を絞ったファイルも足せる
icons/1 枚だけ差し替えず、npm run tauri icon で全サイズを作り直す
build.rsビルドのたびに設定を読み、アイコンの埋め込みや権限の一覧の生成を行う。触らない
Cargo.lock依存クレートの版の記録。手で編集せずコミットする

4. 生成物のフォルダ(gen/ と target/)

フォルダ作られるとき手で編集Git
gen/schemas/Rust をビルドするたびしない除外
gen/android/・gen/apple/tauri android init・tauri ios init必要なら除外しない
target/Rust をビルドするたびしない除外

gen/schemas/ には、使える権限の一覧(acl-manifests.json)と、capabilities/ の JSON で補完を効かせるスキーマが入ります。書き換えても次のビルドで戻りますが、権限の正確な名前に迷ったときに acl-manifests.json を検索するのは便利です。gen/android/ と gen/apple/ はモバイル用のネイティブプロジェクトで、テンプレートの .gitignore は除外していません。

target/ は Cargo の出力で、debug/ に tauri dev、release/ に tauri build の結果が入り、インストーラーは release/bundle/ の下にできます。数 GB になるのは普通で、消しても(cargo clean と同じ)次のビルドが最初からになるだけです。

動作確認

一度 npm run tauri dev で起動して閉じた後、Git の対象になるファイルを確かめます(create-tauri-app は git init しません)。

git init
git ls-files --others --exclude-standard src-tauri

次のように並び、target/ と gen/schemas/ が出てこなければ正しく除外されています(.gitignore の書き方は Git の設定と .gitignore を適用する)。

src-tauri/.gitignore
src-tauri/Cargo.lock
src-tauri/Cargo.toml
src-tauri/build.rs
src-tauri/capabilities/default.json
src-tauri/icons/128x128.png
(icons の残りは省略)
src-tauri/src/lib.rs
src-tauri/src/main.rs
src-tauri/tauri.conf.json

よくあるエラーと対処法

  • default.json の $schema を読み込めないと VS Code が警告する: クローン直後で gen/schemas/ が無いためです。一度 npm run tauri dev を実行すると消えます。
  • 「capability with identifier default already exists」: default.json をコピーして capability を増やし、中の identifier を変えていません。重複してはいけないのはファイル名ではなく identifier です。
  • 「Couldn't recognize the current folder as a Tauri project」という趣旨のエラー: CLI が tauri.conf.json を見つけられていません。プロジェクト直下で実行しているかを確かめます。
  • リリースビルドだけ黒いコンソール画面が開く: main.rs の windows_subsystem の行を消しています。

OS ごとの違いと注意点

  • Windows: 実行ファイルは target\debug\my-app.exe のように .exe 付きで、インストーラーは bundle\msi\ と bundle\nsis\ にできます。OneDrive などの同期フォルダに置くと target/ まで同期され、ファイルのロックでビルドが失敗することがあるので避けます。
  • macOS: インストーラーは bundle/macos/(.app)と bundle/dmg/ です。tauri ios init は macOS でしか使えません。
  • Linux: bundle/deb/・bundle/rpm/・bundle/appimage/ です。
  • 共通: gen/schemas/ には OS 名の付いたスキーマ(windows-schema.json など)と共通名の desktop-schema.json ができます。$schema は、どの OS でも存在する後者を指しています。

関連レシピ

参考リンク(公式ドキュメント)

Web Ninja

この記事を書いた人

Web Ninja ウェブエンジニア (Web Engineer)

会社員ネットワークエンジニアから独立してかれこれ 25 年以上 Web エンジニアとして活動中。普段は JavaScript と Node.js を自在に操り、時には C++ や Perl といった古流の技も嗜みます。近年は Tauri × Rust という新たな武器を手に、デスクトップアプリ開発の最前線を駆け抜けています。「作りたい」を「作れる」に変えるための、実践的な「技」をお届けします。

お問い合わせ: tauri.ninja@gmail.com

内容の誤り・動かないコードを報告する