終局
コード的な記事は少し終わりにしましょう!
現在はpnpm tauri dev
コマンドで実行していますが、それを.exe
ファイルにしてあげてやりたいと思います。
ビルドの前準備
これまで、TypeScript のコード内でエラーがあってもまぁ動いたと思います。
(特に、VSCode で黄色に表示されるような、警告と呼ばれるようなものも)
例として挙げるなら、未使用変数や未使用インポートなど。
そもそも論として、ブラウザ (WebView) では、TypeScript は動作しません。
pnpm tauri dev
では、Vite がなんかうまい事良しなにしてくれるので、TypeScript のコードそのままで動いていました。
Vite?
ヴィートと呼ばれるこの子は、フロントエンド開発をなんかうまい事やってくれる子です。
今回までの記事で Vite がした仕事は、TypeScript で書いてたコードをなんかうまい事ブラウザで動かせるようにしてくれていました。
これは、Vite の開発サーバーというものです。
TypeScript のビルド
ビルドを行っていくにあたって、これから TypeScript のコードを JavaScript に変換されて行くのですが、その際に、TypeScript のコードにエラーがあるとビルドが失敗します。
まずは、そこら辺のエラーを削除していきましょう。
$ pnpm tsc
このコマンドを入れてみましょう。
エラーがあったらなんか出てきます。
正常だったらなんも表示されずにコマンドが終わるかなって思います。
...
tauri-specta
を入れているそこのあなた、多分エラーになると思います。
これはよくない。
VSCode でsrc/bindings.ts
を開いてみると、警告が表示されていると思います。
これは...手動で消してください。
ビルド
さぁ戻ってきました。
まずは試しにビルドしてみましょう。
$ pnpm tauri build
なんの問題もなければ、Finished
とか出てきて成功すると思います。
その出力を見てみると、どうやらsrc-tauri/target/release/bundle/
に.exe
ファイルと.msi
ファイルが生成されているようです。
試しに実行してみましょう。
今回何も触ってないので、マップエディター画面が出てくると思うのですが...
あれ?タイルパレットが出ませんね?
どころか、何も表示されません。多分。
アセット?バンドル?
新規ウィンドウ...
まずはタイルパレットのウィンドウについてお話ししましょうか。
ビルドされた結果については、dist
というフォルダに出力されていると思います。
ここを見ると、HTML ファイルについてはindex.html
しかないと思います。
一方、多分新しいウィンドウのやつは別の HTML ファイルを作ったと思います。が、ここにはない....
これは、Vite の仕様で、デフォルトではindex.html
のみがバンドルされて、設定を変更しないと他の HTML ファイルはバンドルされないのです。
...けど、マップエディターを触ってる間はpnpm tauri dev
でやって、マップが完成して、作った MapClass を置いて初めてビルドしたら良いんじゃないんですかね。えぇ。
画像?
同様にdist
フォルダを覗いてみると、画像ファイルがないと思います。
これじゃあタイル画像も読み込まれないし、なんもできないですよね。
当然このままでいいわけもなく、設定を変えていきましょう。
Tauri の Resource 機能
Tauri は、様々なファイルを同梱するための方法としてresource
という機能を有しています。
まずはsrc-tauri/tauri.conf.json
の中のapp
のbundle
の中に、resources
というキーを追加してみましょう。
"resources": {
"../src/assets/rpg": "resources/rpg"
}
この設定で、../src/assets/rpg
をリソースのresources/rpg
として利用できるようになりました。
(左を右にマッピングするような形。ファイルも実際にコピーされる。)
そのため、TypeScript 内のコードも編集しましょう。
タイルを生成する際にsrc/assets/rpg
を参照していると思いますが、これをresources/rpg
に変更してください。
次にこの 2 つをインポートしましょう。
import { resolveResource } from "@tauri-apps/api/path";
import { convertFileSrc } from "@tauri-apps/api/core";
そして、fetch に渡しているパスをawait resolveResource(...)
で囲み、更にそれをconvertFileSrc(...)
で囲んでください。
await fetch(
convertFileSrc(await resolveResource("resources/rpg/hogehogeTile.png"))
);
await resolveResource
で、resources/...
のパスを実際にそのファイルがあるパスへ変換します。
ですがこれは、ファイルのパスを返すだけで、fetch
に渡すときは http(s)の URL が必要です。
そこで、convertFileSrc
を使うことで、http://assets:localhost/...
のような URL に変換してくれます。
ただ、これだけではまだダメで、CSPの観点から、通常ではこの Assets のリンクにアクセスすることは出来ません。
また、Tauri ではファイルアクセスに対して厳しいセキュリティーを持っているので、リソースにアクセスするための権限設定も必要です。
まずはfs-plugin
をインストールしましょう。
$ pnpm tauri add fs
そしてsrc-tauri/capabilities/default.json
でfs:allow-resource-read-recursive
を追加します。
{
"permissions": [
...
"fs:allow-resource-read-recursive"
]
}
そしてさらにpermissions
の中に、アクセス許可をしたいパス、今回はリソースなので以下のように追加します。
{
"permissions": [
...
"fs:allow-resource-read-recursive",
{
"identifier": "fs:scope",
"allow": [{ "path": "$RESOURCE/**" }]
}
]
}
分かりにくいですが、$RESOURCE
とresources
は別物です。
$RESOURCE
はリソースのパスを指します。
resources
は勝手に名付けただけで、何でもよくて...
このresources
を正式なパスで表すなら$RESOURCE/resources
となります。
最後に、src-tauri/tauri.conf.json
のapp
のsecurity
という項目を以下のように編集します。
"security": {
"csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost",
"assetProtocol": {
"enable": true,
"scope": ["$RESOURCE/**"]
}
}
これで実行してみると...?
結果
~~ワザップ (すいません時間無くて中途半端に切ってしまいました) ~~
この作業についてはあんまり日本語ドキュメントがなかったので軽くですが書いてみました。
ここから先は公式ドキュメントなどをモグモグしながら君自身で成長していっておくれ!
ちなみに CSP の設定をサンプルのままにしているため、このままだと場合によっては恐ろしいことが起こるかも。
以上で!