Tauriメモ
プロジェクト作成、開発、ビルド関係
新規プロジェクト作成(Tauri+Vite+React+Typescript)
作業フォルダに移動したのち(まだアプリフォルダはつくらない)
フロントエンドの作成
code:sh
yarn create vite
✔ Project name: ... <プロジェクトの名前=フォルダ名>
✔ Select a framework: » React
✔ Select a variant: » TypeScript
...
tauri-cliのインストール
code:sh
cd <プロジェクトの名前=フォルダ名>
yarn add -D @tauri-apps/cli
...
tauriのインストール
code:sh
yarn tauri init
✔ What is your app name? · <プロジェクトの名前>
✔ What should the window title be? · <プロジェクトの名前>
✔ Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that will be created? · ../dist <-- 書き換えが必要
✔ What is your frontend dev command? · npm run dev <-- このままでもyarnは使える
✔ What is your frontend build command? · npm run build <-- このままでもyarnは使える
あとは<プロジェクトフォルダ>をVSCodeで開いて開発開始
バックエンドはsrc-tauri > src > main.rc、
フロントエンドはsrc > main.tsxおよびsrc > App.tsxです
実行
code:sh
yarn tauri dev
ビルド
code:sh
yarn tauri build
注:サンプルのままビルドするとエラーが出る。詳細は後述「You must change the bundle identifier...」
※なお昔のバージョン(おそらく1.1以前)ではcreate tauri-app時にVueやReactなどもサポートしていてコマンド一発でセットアップできた。現在のバージョン(おそらく1.2~)では、yewかvanilla(HTML+Javascript)のみ対応になった。フロントエンドのインストールは自分でやれというスタイルになったらしい。 VSCode上でエラー:モジュール 'vue' の宣言ファイルが見つかりませんでした。…
code:cmd
npm i --save-dev @types/vue
VSCode上でエラー:Cannot find module '@tauri-apps/api' or its corresponding type declarations.
code:cmd
npm i @tauri-apps/api
ビルド時にエラー:ERROR: Top-level await is not available in the configured target environment...
なぜか意味不明な箇所でエラーが出ているが、私の場合main.tsの中で使っていたawaitを削るとビルドが通った。
開発(dev)時にはこのエラーは出ない。
ビルド時にエラー: You must change the bundle identifier in tauri.conf.json > tauri > bundle > identifier.
バンドルIDがデフォルトでcom.tauri.devになっているのでこれを自分のものに書き換えなさいよといっている。これはアプリケーション開発においてアプリの開発者を識別するもので、例えばスマホアプリの場合アップルのAppStoreに登録するときなどに必要になるものだったりする。適当にそれっぽいものに書き換えよう。自分のドメインを持っている人はそのアドレスを逆にしたもの+アプリ名などとすれば良いと思う。
ローカルファイルにアクセスする方法
ファイルダイアログを使うならAllowlistにdialog>all/open/saveを追加
code:json
"tauri": {
"allowlist": {
"dialog": {
"all": true,
"open": true,
"save": true
}
...
viteのURLをローカルファイルアドレスに変換するためにtauri::convertFileSrc()を利用する必要があり、そのためにAllolistにprotocol>all/asset/assetScopeが必要。net::ERR_CONNECTION_REFUSEDが出る場合はこれが原因 code:json
"protocol": {
"all": true,
"asset": true,
}
Allowlistの書き方
アプリの許可設定。プロジェクトフォルダ>src-tauri>tauri.conf.json 内で設定する。
code:json
{
...
"tauri": {
"allowlist": {
"all": false, <-- 最初に全禁止しておき、あとから部分的に解除する
"fs": {
"all": false, <-- 同上
"readFile": true, <-- ファイルの読み込みを許可する
"writeFile": true <-- ファイルの書き込みを許可する
"scope": [ <-- 扱えるフォルダの範囲
"$TEMP/*", <-- C:\Users\<username>\AppData\Temp 以下
"$APPCONFIG/*" <-- C:\Users\<username>\AppData\Roaming\<APP ID>\ 以下
],
}
},
利用する側
code:js
await fs.writeTextFile('app.conf', 'contents', { dir: fs.BaseDirectory.AppConfig })
なお<APP ID>フォルダは自動で掘ってくれないので自分で掘ること
バックエンド(Rust)関係
複数のtauri commandの登録
code:rust
fn main() {
tauri::Builder::default()
//invoke_handlerは1回のみ。複数回使うと上書きされる
.invoke_handler(tauri::generate_handler![
testfunc, //コマンド例1
read_text_file, //コマンド例2
run_command, //コマンド例3
file_move, //コマンド例4
write_text_file //コマンド例5
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
パラメータ名はsnake_case(Rust)とcamelCase(JS)で勝手に変換される
code:rust
//バックエンド(Rust)
async fn get_number(param_name: String) -> i32 {
...
}
code:js
//フロントエンド(JS)
//気を利かせてparam_nameなどとすると「パラメータがない」と怒られます
invoke("get_number", { paramName: "Hello.txt" }).then( (result) => {
...
})
tauri::commandの戻り値について
勉強中
フロントエンド(UI)関係
React-tsでのButtonのonClickイベントの型は
code:html
<button onClick={buttonClicked}>button</button>
code:js
function buttonClicked(e: React.MouseEvent<HTMLButtonElement>) {
...
}
ぶっちゃけanyでも良し
テキストの選択を禁止する
index.htmlのhtmlタグまるごとにCSSで選択禁止設定する
code:html
<html lang="ja"
style="-moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;-o-user-select:none;"
unselectable="on" onselectstart="return false;">
ドラッグによるテキストの選択、テキストのダブルクリックで単語の選択、が無効化する
textarea,input内での「すべて選択」や「Ctrl+A」が無効化する
textarea,input内でのドラッグやダブルクリックによる文字列選択は有効
ボタン、リンク類(ローカル、グローバル問わず)のクリックは有効(target="_blank"でブラウザを開くにはさらにallowlistで有効化が必要)
テキストエリアのサイズ変更も可能
画像・リンク、input内で選択したテキストのドラッグは可能
画像、リンクのドラッグを禁止する
画像・リンクのドラッグを禁止するにはimgタグにdraggable="false"を設定する
code:html
<img src="/vite.svg" alt="Vite logo" draggable="false" />
テキストエリアのサイズ変更を禁止する
テキストエリアのリサイズ禁止はresize:noneスタイルを適用する(以下はReact(JSX)の場合)
code:jsx
<textarea style={{ resize: "none" }}>
some text
</textarea>
なおリサイズの方向を制限することもできる
Tailwindの導入
Typescriptの場合、2ステップ目 content: ["./src/**/*.{html,js}"]の部分を、content: ["./src/**/*.{html,js,ts,jsx,tsx}"]とする
スタイルが反映されない場合、 プロジェクトルートにpostcss.config.cjsを作成し、内容を以下のようにする
code:js
module.exports = {
plugins: {
tailwindcss: {}
}
}
main.tsx内にimport "./input.css";(ステップ2で作ったファイルへのパス)を入れることを忘れずに