TauriでDeno Freshが動くか試す
Prerequirements:
- Deno 1.34.3
- Rust 1.70.7
Deno Freshプロジェクト作成
$ deno run -A -r https://fresh.deno.dev tauri-deno-fresh
Devサーバーを起動して挙動を確認しておく
$ deno task start
Tauriインストール&セットアップ
$ cargo install tauri-cli
...
Installed package `tauri-cli v1.4.0` (executable `cargo-tauri`)
$ cd tauri-deno-fresh
$ cargo tauri init
✔ What is your app name? · Tauri with Deno Fresh
✔ What should the window title be? · Tauri with Deno Fresh
✔ Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that will be created? · ../build
✔ What is the url of your dev server? · http://localhost:8000
✔ What is your frontend dev command? · deno task start
✔ What is your frontend build command? · deno task build
以下を参考にファイルを編集・作成する。
buildタスクとesbuildのインポートを追加。
{
"lock": false,
"tasks": {
"start": "deno run -A --watch=static/,routes/ dev.ts",
"build": "deno run -A build.ts",
"update": "deno run -A -r https://fresh.deno.dev/update ."
},
"imports": {
"$fresh/": "https://deno.land/x/fresh@1.2.0/",
"preact": "https://esm.sh/preact@10.15.1",
"preact/": "https://esm.sh/preact@10.15.1/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.1.0",
"@preact/signals": "https://esm.sh/*@preact/signals@1.1.3",
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.2.3",
"$std/": "https://deno.land/std@0.190.0/",
"esbuild": "https://deno.land/x/esbuild@v0.18.7/mod.js"
},
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}
ビルドファイルを作成。
import * as esbuild from "esbuild";
import { posix } from "$std/path/mod.ts";
const options: esbuild.BuildOptions = {
entryPoints: [posix.resolve("main.ts")],
bundle: true,
outdir: posix.resolve("build"),
minify: true,
sourcemap: "external",
};
await esbuild.build(options);
esbuild.stop();
esbuildでビルドしてみる。
$ deno task build
Task build deno run -A build.ts
✘ [ERROR] Top-level await is currently not supported with the "iife" output format
main.ts:12:0:
12 │ await start(manifest);
╵ ~~~~~
✘ [ERROR] Could not resolve "$std/dotenv/load.ts"
main.ts:7:7:
7 │ import "$std/dotenv/load.ts";
╵ ~~~~~~~~~~~~~~~~~~~~~
You can mark the path "$std/dotenv/load.ts" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "$fresh/server.ts"
main.ts:9:22:
9 │ import { start } from "$fresh/server.ts";
╵ ~~~~~~~~~~~~~~~~~~
You can mark the path "$fresh/server.ts" as external to exclude it from the bundle, which will
remove this error.
▲ [WARNING] "import.meta" is not available with the "iife" output format and will be empty [empty-import-meta]
fresh.gen.ts:19:11:
19 │ baseUrl: import.meta.url,
╵ ~~~~~~~~~~~
You need to set the output format to "esm" for "import.meta" to work correctly.
✘ [ERROR] Could not resolve "$fresh/runtime.ts"
routes/index.tsx:1:21:
1 │ import { Head } from "$fresh/runtime.ts";
╵ ~~~~~~~~~~~~~~~~~~~
You can mark the path "$fresh/runtime.ts" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "@preact/signals"
routes/index.tsx:2:26:
2 │ import { useSignal } from "@preact/signals";
╵ ~~~~~~~~~~~~~~~~~
You can mark the path "@preact/signals" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "$fresh/runtime.ts"
components/Button.tsx:2:27:
2 │ import { IS_BROWSER } from "$fresh/runtime.ts";
╵ ~~~~~~~~~~~~~~~~~~~
You can mark the path "$fresh/runtime.ts" as external to exclude it from the bundle, which will
remove this error.
error: Uncaught (in promise) Error: Build failed with 6 errors:
components/Button.tsx:2:27: ERROR: Could not resolve "$fresh/runtime.ts"
main.ts:7:7: ERROR: Could not resolve "$std/dotenv/load.ts"
main.ts:9:22: ERROR: Could not resolve "$fresh/server.ts"
main.ts:12:0: ERROR: Top-level await is currently not supported with the "iife" output format
routes/index.tsx:1:21: ERROR: Could not resolve "$fresh/runtime.ts"
...
let error = new Error(`${text}${summary}`);
^
at failureErrorWithLog (https://deno.land/x/esbuild@v0.18.7/mod.js:1615:15)
at https://deno.land/x/esbuild@v0.18.7/mod.js:1027:25
at https://deno.land/x/esbuild@v0.18.7/mod.js:972:52
at buildResponseToResult (https://deno.land/x/esbuild@v0.18.7/mod.js:1025:7)
at https://deno.land/x/esbuild@v0.18.7/mod.js:1054:16
at responseCallbacks.<computed> (https://deno.land/x/esbuild@v0.18.7/mod.js:676:9)
at handleIncomingPacket (https://deno.land/x/esbuild@v0.18.7/mod.js:731:9)
at readFromStdout (https://deno.land/x/esbuild@v0.18.7/mod.js:652:7)
at https://deno.land/x/esbuild@v0.18.7/mod.js:1901:11
at eventLoopTick (ext:core/01_core.js:183:11)
いっぱい出ますねえ。1つ1つ潰していくぞ。
まずこれら:
✘ [ERROR] Top-level await is currently not supported with the "iife" output format
main.ts:12:0:
12 │ await start(manifest);
╵ ~~~~~
▲ [WARNING] "import.meta" is not available with the "iife" output format and will be empty [empty-import-meta]
fresh.gen.ts:19:11:
19 │ baseUrl: import.meta.url,
╵ ~~~~~~~~~~~
You need to set the output format to "esm" for "import.meta" to work correctly.
どっちも、アウトプット・フォーマットがiife
だとダメらしい。
esbuildのイシュー - support for top level awaitに--format=esm
でってある。Denoはesmだし丁度いいね。
const options: esbuild.BuildOptions = {
entryPoints: [posix.resolve("main.ts")],
bundle: true,
+ format: "esm",
outdir: posix.resolve("build"),
minify: true,
sourcemap: "external",
};
deno task build
を再実行したらこれらのエラー消えた。
これら全部同じ理由っぽいな。
✘ [ERROR] Could not resolve "$std/dotenv/load.ts"
main.ts:7:7:
7 │ import "$std/dotenv/load.ts";
╵ ~~~~~~~~~~~~~~~~~~~~~
You can mark the path "$std/dotenv/load.ts" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "$fresh/server.ts"
main.ts:9:22:
9 │ import { start } from "$fresh/server.ts";
╵ ~~~~~~~~~~~~~~~~~~
You can mark the path "$fresh/server.ts" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "$fresh/runtime.ts"
components/Button.tsx:2:27:
2 │ import { IS_BROWSER } from "$fresh/runtime.ts";
╵ ~~~~~~~~~~~~~~~~~~~
You can mark the path "$fresh/runtime.ts" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "$fresh/runtime.ts"
routes/index.tsx:1:21:
1 │ import { Head } from "$fresh/runtime.ts";
╵ ~~~~~~~~~~~~~~~~~~~
You can mark the path "$fresh/runtime.ts" as external to exclude it from the bundle, which will
remove this error.
✘ [ERROR] Could not resolve "@preact/signals"
routes/index.tsx:2:26:
2 │ import { useSignal } from "@preact/signals";
╵ ~~~~~~~~~~~~~~~~~
You can mark the path "@preact/signals" as external to exclude it from the bundle, which will
remove this error.
あ〜、$
や@
で始まるspecifierのImportMapが解決されてませんなぁ……
esbuild_deno_loaderっていうesbuildプラグインがあって、モジュールを解決してくれるっぽい。
imports書いて、
{
...
"imports": {
...
"esbuild": "https://deno.land/x/esbuild@v0.18.7/mod.js",
"esbuild-deno-loader": "https://deno.land/x/esbuild_deno_loader@0.8.1/mod.ts"
},
...
}
プラグイン追加して、
...
import { denoPlugins } from "esbuild-deno-loader";
...
const options: esbuild.BuildOptions = {
...
plugins: [
...denoPlugins(),
],
};
...
実行!
$ deno task build
Task build deno run -A build.ts
✘ [ERROR] Module not found "file:///Users/babie/src/github.com/babie/tauri-deno-fresh/$std/dotenv/load.ts". [plugin deno-loader]
main.ts:7:7:
7 │ import "$std/dotenv/load.ts";
╵ ~~~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Module not found "file:///Users/babie/src/github.com/babie/tauri-deno-fresh/$fresh/server.ts". [plugin deno-loader]
main.ts:9:22:
9 │ import { start } from "$fresh/server.ts";
╵ ~~~~~~~~~~~~~~~~~~
✘ [ERROR] Module not found "file:///Users/babie/src/github.com/babie/tauri-deno-fresh/routes/$fresh/runtime.ts". [plugin deno-loader]
routes/index.tsx:1:21:
1 │ import { Head } from "$fresh/runtime.ts";
╵ ~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Module not found "file:///Users/babie/src/github.com/babie/tauri-deno-fresh/components/$fresh/runtime.ts". [plugin deno-loader]
components/Button.tsx:2:27:
2 │ import { IS_BROWSER } from "$fresh/runtime.ts";
╵ ~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Module not found "file:///Users/babie/src/github.com/babie/tauri-deno-fresh/routes/@preact/signals". [plugin deno-loader]
routes/index.tsx:2:26:
2 │ import { useSignal } from "@preact/signals";
╵ ~~~~~~~~~~~~~~~~~
ファーw w w w w
一緒やんけ
どうも、esbuild_deno_loaderが依存してるimportmapが$
とか@
が付いた場合に対応してないみたいやね。
イシュー出した:
ソースコード見たら違った。esbuild_deno_loader
のバグだ。
esbuild
がonLoad()
やonResolve()
で渡してくるargs.namespace
がデフォルトでfile
なのをそのまま使ってるから起こるっぽいね。
- namespace
This is the namespace of the module containing this import to be resolved, as set by the on-load callback that loaded this file. This defaults to thefile
namespace for modules loaded with esbuild's default behavior. You can read more about namespaces here.
この辺もイシューに追記しときましたわーん
なんか音沙汰あるかな?と見に行ったら、音沙汰はないけどREADMEの"Using with other plugins"にこの件書いてあった:
denoPlugins
じゃなくてdenoResolverPlugin
とdenoLoaderPlugin
に分けてimportして、denoResolverPlugin
に適切なオプションを与えて変換しろということみたい。
気づかなくて悪いことした……手元で動いたらイシュー閉じる。