|
| 1 | +--- |
| 2 | +title: Hello, Deno v1.0.0 |
| 3 | +created: 1589719008195 |
| 4 | +--- |
| 5 | + |
| 6 | +Deno 1.0.0 がリリースされて、ちょっと遊んでみたので、その感想。 |
| 7 | + |
| 8 | +## 圧倒的ゼロインストール感 |
| 9 | + |
| 10 | +自分は mac なので `brew install deno` しました。`deno` コマンドが入ります。セットアップはこれで終わり。 |
| 11 | + |
| 12 | +GitHub の trending に上がっていた https://github.com/oakserver/oak という web server を試してみます。 |
| 13 | + |
| 14 | +```ts |
| 15 | +// server.ts |
| 16 | +import { Application } from "https://deno.land/x/oak/mod.ts"; |
| 17 | +const app = new Application(); |
| 18 | + |
| 19 | +app.use((ctx) => { |
| 20 | + ctx.response.body = "Hello World!"; |
| 21 | +}); |
| 22 | + |
| 23 | +await app.listen({ port: 8000 }); |
| 24 | +``` |
| 25 | + |
| 26 | +このコードを保存して、実行します |
| 27 | + |
| 28 | +``` |
| 29 | +deno run --allow-net server.ts |
| 30 | +``` |
| 31 | + |
| 32 | +これだけ。コマンド実行時に `https://deno.land/x/oak/mod.ts` から依存がダウンロードされて、サーバーが立ちます。 |
| 33 | + |
| 34 | +ここで、インストールコマンドを何も叩いてないのに注目してください。Deno では実行時に URL が静的に解決されて実行されます。パッケージや `package.json` といったものがありません。 |
| 35 | + |
| 36 | +`--allow-net` も特徴的ですね。deno ではデフォルトでは権限が限定されています。ローカルファイルに触るには、 `--allow-read` や `--allow-write` が必要になります。 |
| 37 | + |
| 38 | +## 開発環境 |
| 39 | + |
| 40 | +ここはまだ難があるように思います。 |
| 41 | + |
| 42 | +Deno ではモジュールシステムやパス解決が純粋な TypeScript と非互換(`.ts` の拡張子資料略ができない) ので、 vscode 拡張などで専用の typescript server を起使う、といったソリューションが試みられています。 で、`axetroy/deno` と `justjavac/deno` があるんですが、どちらも中途半端です。どちらも import-map 対応のオプションがあるように見えるんですが、動きません。ちょっと変なことをすると、すぐ動かなくなります。 |
| 43 | + |
| 44 | +deno-ja の slack で聞いた限りでは justjavac の方が公式に近い立ち位置なんですが、 axetroy/deno の fork らしいんですが、まだ axetroy/deno のがちゃんと動いてるみたいです。 |
| 45 | + |
| 46 | +(そもそも deno やってる人たちは vscode を TS の違反の警告を無視するのになれてるらしく、エディタ支援はない前提っぽいで書いてる人が多い印象) |
| 47 | + |
| 48 | +## モジュールシステム |
| 49 | + |
| 50 | +公式には deno.land/std と、サードパーティ相当の deno.land/x があります |
| 51 | + |
| 52 | +- https://deno.land/std |
| 53 | +- https://deno.land/x |
| 54 | + |
| 55 | +それとは別に、ESM で node の標準ライブラリに頼らずビルドされたコードは import できます。 npm をバックエンドにした CDN としては、以下のようなものがあります。 |
| 56 | + |
| 57 | +- [jsDelivr \- A free, fast, and reliable Open Source CDN for npm & GitHub](https://www.jsdelivr.com/) のうち、rollup の ESM ビルドが配布されているもの |
| 58 | +- [UNPKG](https://unpkg.com/) の `?module` での esm build |
| 59 | +- [Pika CDN](https://www.pika.dev/cdn) で ESM 用にビルドされた JS |
| 60 | + |
| 61 | +## Next.js クローンを作ろうとしてみた |
| 62 | + |
| 63 | +[mizchi/toxen](https://github.com/mizchi/toxen) っていうリポジトリで、 next.js っぽいサーバー書いて遊んでました。(まだ実験中です) |
| 64 | + |
| 65 | +技術スタック |
| 66 | + |
| 67 | +- deno |
| 68 | +- snowpack |
| 69 | +- oak |
| 70 | +- preact |
| 71 | +- htm |
| 72 | + |
| 73 | +snowpack は一種のフロントエンド向けのバンドラーなんですが、webpack に頼らずネイティブ ESM で動くモジュールを吐いて、それを importmap を、 deno の importmap として使う、といった方法を選んでみました。 |
| 74 | + |
| 75 | +- [Snowpack](https://www.snowpack.dev/) |
| 76 | +- [WICG/import\-maps: How to control the behavior of JavaScript imports](https://github.com/WICG/import-maps) |
| 77 | + |
| 78 | +やってみた感じ、 `import { h } from "preact"` という感じの、比較的 node と似たような書き味で、快適です。 |
| 79 | + |
| 80 | +ただ、事前に snowpack でビルドして、動的に `pages/*.ts` を読んで、 `dist/*.js` に吐き出して…とやっていたら、結局こんな感じの実行スクリプトに |
| 81 | + |
| 82 | +``` |
| 83 | +snowpack && deno run --unstable --allow-write --allow-read --allow-net --importmap web_modules/import-map.json server.ts |
| 84 | +``` |
| 85 | + |
| 86 | +deno ならではの工夫として、next.js のクローンなので `pages/*.ts` のエンドポイントをターゲットに SSR する必要があるんですが、webpack や rollup のバンドラを使うのではなく `Deno.bundle(Deno.cwd() + "/pages/foo.ts")` みたいなコードで Deno の内部バンドラをそのまま使って、静的な JS を吐いてブラウザに食わせています。 |
| 87 | + |
| 88 | +あと、 amp + amp-script(worker-dom) で動かしているので、 amp ページでありながら動的に動く画面を作れます。 worker-dom は技術的な詳細はここでは解説しませんが、動的なコンポーネントを初期化するには SSR が必須です。 |
| 89 | + |
| 90 | +[Documentation: <amp\-script> \- amp\.dev](https://amp.dev/documentation/components/amp-script/) |
| 91 | + |
| 92 | +React ではなく preact なのは、 amp-script の 150kb 制限をクリアするためです。tsx を使っていなくて htm なのは、preact pragma を使って tsx を書くと React の型がないので、実行時例外になるのをかわすためのワークアラウンドです。 |
| 93 | + |
| 94 | +今後の TODO として、動的 URL に対応する、Deno ライブラリとして抽象的にする、export できるようにする、といった方向性があると思ってるんですが、これを本気で開発するかはまだ悩んでいて、もうちょっと Deno 自体が安定してほしい気持ちもありますね。 |
| 95 | + |
| 96 | +ただ、このブログのような SSG なら、ランタイムに deno がいないので、比較的安心して採用できる気がしました。 |
| 97 | + |
| 98 | +## Universal JavaScript を考え直す |
| 99 | + |
| 100 | +ここまでやってみて、 Deno に対応する、というのは 2 つの水準があると思いました。 |
| 101 | + |
| 102 | +- CLI ツールなど向けに、 deno の標準ライブラリを使って、 `.ts` で deno べったりで書き直す |
| 103 | +- Universal な JavaScript として、 rollup でビルドして配布する |
| 104 | + |
| 105 | +要は esm に対応してさえいれば読み込みはできるので、Universal な JavaScript としては、rollup でビルドしていると deno 対応している、と言えなくはないです。npm にあげてしまった後は、npm の CDN である jsdelivr を経由して読み込むといいでしょう。 |
| 106 | + |
| 107 | +deno を使っていくかどうかはともかく、 snowpack など esm 前提の実行環境なども増えてるので、この辺を意識しておくと、将来的な可用性が増えるのではないでしょうか。 |
0 commit comments