Deno 1.45 で workspace に対応した。 Fresh でも使えないかと思い、試してみたら相性が良くないようなので暫定対応した。
参考
やってみた、一部動かなかった 以下のようなディレクトリ構成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 . ├─app-a │ ├─components │ ├─islands │ ├─routes │ │ ├─api │ │ `─greet │ `─static ├─app-b │ ├─components │ ├─islands │ ├─routes │ │ ├─api │ │ └─greet │ `─static ├─share <= app-a, app-b で共通のモジュール `─deno.json <= workspace の設定がされる deno.json
app-a, app-b はそれぞれ独立したアプリケーションで、共通の share ディレクトリにあるモジュールを参照する。
./deno.json
以下のように記述する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 { "lock" : false , "lint" : { "rules" : { "tags" : [ "fresh" , "recommended" ] } } , "exclude" : [ "**/_fresh/*" ] , "imports" : { "$fresh/" : "https://deno.land/x/fresh@1.6.8/" , "preact" : "https://esm.sh/preact@10.19.6" , "preact/" : "https://esm.sh/preact@10.19.6/" , "@preact/signals" : "https://esm.sh/*@preact/signals@1.2.2" , "@preact/signals-core" : "https://esm.sh/*@preact/signals-core@1.5.1" , "tailwindcss" : "npm:tailwindcss@3.4.1" , "tailwindcss/" : "npm:/tailwindcss@3.4.1/" , "tailwindcss/plugin" : "npm:/tailwindcss@3.4.1/plugin.js" , "$std/" : "https://deno.land/std@0.216.0/" , "share" : "./share/lib.ts" } , "compilerOptions" : { "jsx" : "react-jsx" , "jsxImportSource" : "preact" } , "nodeModulesDir" : false , "workspace" : [ "./app-a" , "./app-b" ] }
./app-a/deno.json
には以下のように記述する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 { "tasks" : { "check" : "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx" , "cli" : "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -" , "manifest" : "deno task cli manifest $(pwd)" , "start" : "deno run -A --watch=static/,routes/ dev.ts" , "build" : "deno run -A dev.ts build" , "preview" : "deno run -A main.ts" , "update" : "deno run -A -r https://fresh.deno.dev/update ." } , "lint" : { "rules" : { "tags" : [ "fresh" , "recommended" ] } } , "exclude" : [ "**/_fresh/*" ] , "imports" : { } , "compilerOptions" : { "jsx" : "react-jsx" , "jsxImportSource" : "preact" } }
この状態で app-a ディレクトリから、deno task start
すると、以下のエラーが発生する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Error: Build failed with 1 error: components/Button.tsx:2:27: ERROR: [plugin: deno-resolver] specifier was a bare specifier, but was not remapped to anything by importMap. at failureErrorWithLog (https://deno.land/x/esbuild@v0.20.2/mod.js:1626:15) at https://deno.land/x/esbuild@v0.20.2/mod.js:1034:25 at runOnEndCallbacks (https://deno.land/x/esbuild@v0.20.2/mod.js:1461:45) at buildResponseToResult (https://deno.land/x/esbuild@v0.20.2/mod.js:1032:7) at https://deno.land/x/esbuild@v0.20.2/mod.js:1061:16 at responseCallbacks.<computed> (https://deno.land/x/esbuild@v0.20.2/mod.js:679:9) at handleIncomingPacket (https://deno.land/x/esbuild@v0.20.2/mod.js:739:9) at readFromStdout (https://deno.land/x/esbuild@v0.20.2/mod.js:655:7) at https://deno.land/x/esbuild@v0.20.2/mod.js:1974:11 at eventLoopTick (ext:core/01_core.js:168:7) { errors: [Getter/Setter], warnings: [Getter/Setter] }
これに対応するには、app-a/deno.json
に以下のような記述を追加する。
1 2 3 4 5 6 7 8 { "imports" : { "preact" : "https://esm.sh/preact@10.19.6" , "preact/" : "https://esm.sh/preact@10.19.6/" , "@preact/signals" : "https://esm.sh/*@preact/signals@1.2.2" , "@preact/signals-core" : "https://esm.sh/*@preact/signals-core@1.5.1" , } }
これで、エラーが解消される。 確認してみると、islands で参照しているようなモジュールは、deno.json
に記述の必要があった。
しかし、こうなるとimportsを上書きするわけでもないのに、importsに書く必要がある。 islands で最近はHonoRPCをよく使うが、これも同様に記述が必要になる。 というわけで、workspace の導入は、Freshにはまだよくなさそうである。 Issueを出してみたので、経過は見守りたい。
暫定対応 仕方ないので、app-a
、app-b
から share
を参照する際は、相対パスで指定することにした。
1 2 3 4 5 { "imports" : { "share" : "../share/lib.ts" } }
また、deno deploy 展開用のgithub actionは、以下のように記述する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 name: Deploy-App-A on: push: branches: main pull_request: branches: main jobs: deploy: name: Deploy runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - name: Clone repository uses: actions/checkout@v4 - name: Install Deno uses: denoland/setup-deno@v1 with: deno-version: v1.x - name: Build step run: "cd app-a && deno task build" - name: Upload to Deno Deploy uses: denoland/deployctl@v1 with: project: "hogehoge" entrypoint: "app-a/main.ts" root: "./"
これで、共通部分のモジュールを参照できる。 (app-bも同様にする)
というわけで、暫定対応で乗り切ることにした。 暫定対応といいつつ、何も解決してないのではという感はある。fresh.gen.ts
のように、islands 用のmoduleのload用のファイルは自動作成が望ましいように考えられる。
では。