tarui/reactを利用して個人で勉強している。Dockerを使ってwebアプリよりもシンプルだからだ。以前はelectronを使っていたが、新しいもの好きだしRustにも触れてみたかったからtauriを選んだ。Rustよりもreactの勉強と言える。
何に苦戦しているかって?アプリが展開された場所の取得する方法がわからないからだ。デフォルト設定を書いたconfigファイルなどを用意しておき、アプリが立ち上がったら読み込みたい。tauriはwindows用のexeファイルを作れる。その場所がどこであれexeと同じ階層にあるファイルを読み込みたいだけだ。そのためにはアプリのある相対パスが必要だ。
最初読み込むということでfile read方法を検索、公式にそれっぽいのが出てきた
こう書けばAppディレクトリがstringで返ってくると書いてある。だけどね、これだと/AppData/Roming配下のディレクトリを取得するんだな
import { appDir } from '@tauri-apps/api/path';
const appDirPath = await appDir();
そうじゃない。配布されたアプリをどこに配置するかはユーザによる。一時データのディレクトリを知りたいわけじゃない。だがどれも固定ディレクトリを取得する関数ばかりだ。同じ悩みを抱えた人だっているはずだ。実際にstackoverflowにはいた。
Tauri - How can I read a file inside the project folder? - Stack Overflow
回答者は理解していないらしい。このやり方もAppData下を見に行くだけだ。この調子で数時間調べまくってギブアップした。
2日後、アマプラでboysのシーズン3後半を見ながらふと思いついた。file readで検索するから出てこないんだ。単純にfile pathで検索すりゃあいいのでは?、と。ラストエピソードを見る前にPCを立ち上げ検索する。そうして出てきたページを見たときの希望と確認した後の落胆ときたら想像できるだろうか。
同じことだった。書いてある関数はどれもAppDataやUser/PublicだのUser/Downloadだのの固定パスを取得するものばかり。想像する限り絶対にあるはずのexeファイルのある場所の指定ができない。
回避方法は色々考えられる。tsファイルに設定コードを書いて、どのページにもそのtsファイル内のコードを読むとか。あるいはアプリの一番最初の立ち上げ時にファイルアップロード処理をしてもらい(なぜかファイルアップロード関数はある)exeと同じ階層の設定ファイルを読み込んでもらうとか。設定ページを作ってデフォルト値の入ったinput textとsubmitボタンを用意するとか。
どれもこれもなんだかおかしい気がする。外部設定ファイルの読み込みぐらいできるはずじゃないか。メモアプリのフォントの大きさとかの設定値のデフォルトを読み込んで、変更があれば設定ファイルに書き込む、それぐらいできるはずじゃないか。ダイアログ表示関数があるので、ファイルアップロードのデフォルトパスはどこかと思ったらDocumentディレクトリであった。ファイルアップロードなんだからexeがある場所なんじゃないかと思った。もしかしたらdevで立ち上げている仮想的な状態だから駄目なのであってexeに固めてからなら違う結果がでるかもと思いbuildする。結果は同じ。
もうなんだかなあ、と思って公式の関数を一つずつ試す。どれもこれもどこかの固定パスだった。だがリストの中にピンとくる文字列が。
import { resourceDir } from '@tauri-apps/api/path';
const resourceDirPath = await resourceDir();
resource!
直前にbuildしてexeを試していたからピンときた。buildされたファイル郡の中にresourcesというディレクトリがあった。これか?と思い試すと、ビンゴ!
開発環境の場合\src-tauri\target\debugディレクトリを、build後は\src-tauri\target\releaseディレクトリを表示し、そこに置いたテキストファイルを読み込めた!buildファイル郡のresourcesは何の関係もなかったが、気づきにつながった。
なんということでしょう、3日後に解決できたのはまさに匠の調査!
1日目にfsの公式の中の$RESOURCEに気づいてればもっと早かった。しかしfsではなくpathという発想がなかったので遅かった。
stackoverflowに回答を追加して満足。
しかし自分の調査能力のなさにうんざりした。
絶望的だと思った。
満足したのでboysのラストエピソード見る。