Denoばた会議 Monthly 第7回
2022年3月20日開催。
connpassリンク。
今月のアップデートを追う
Denoのアップデートを追っていくLT。
そのあとの雑談込みでザックリと箇条書き。
Deno v1.20
permissions
オプションの挙動が変更
- 破壊的変更
Deno.test
のpermissions
で明示されていないものはデフォルトで無効化されていなかった- 直感的ではなかったのでデフォルト無効化に変更された。
- 実は直っているようで直ってなかった
permissions: {}
だとすべての権限が継承される- このPRで直される
- 次のリリースで直っているはず
deno task
コマンド
deno.json(c)
にtasks
が追加され、deno task start
のようなコマンドを実行可能になる- 元々は
deno script
コマンドで1ヶ月くらいやっていた - その後に
deno task
に変更された - cross-env対応や細かい機能がある
deno.json(c)
という設定ファイルに書けるpackage.json
みたいな感じ- shellが書ける
package.json
の場合は、Linuxの書き方をすればWindows環境では動かなかった- Denoはdeno_task_shellという独自shellを使っているため、環境に関係なく動く
cp
やsleep
やecho
など、複数のビルトインコマンドが存在する- Davidさんという言語的な仕事が得意な中堅社員が作った
- 社内でビジネスの用事でRyanさんがいない週があり、そのタイミングでmainにマージされた
- 帰ってきたRyanさんが合意がされていないと異論
- それに社内で異論が出て、週の初めのMTGで議論し、unstableなら妥協しようという路線になった
- Ryanさんはあまり納得してなさそう
- クロスプラットフォームが入っているが実質npm run script
- npm run scriptsはshell
- Denoは今までshellという概念がなかった
- 『shellという古い概念を感じさせずに使ってほしいのがDeno』という考え
- Web的な仕組みでやれるといいのでは
- shellを取り込むのは進化の方向性としていかがなものか
- Denoのスクリプトを直接書けるようにすればいいのでは? という案もあった
- そこでプログラミングしてしまうだろうし、エスケープなどが入って開発者体験が悪いので、あまりよくなさそう
- 現実的な見方の人は歓迎した
- バージョンが進んでいくうちに評価が進み、そこで方向性も変わるだろう
deno bench
コマンド
Deno.bench
の内部に関数を書き、deno bench --unstable
と書くことでコードのベンチマークを取得できる- メソッドのパターンやファイルパターンは
Deno.test
と同じ *.bench.ts
を拾ってきて実行してくれる- 何回も実行して平均の時間出してくれる
- 遅くなってるか速くなってるかをこれで確認しながら開発すれば、モジュールが速くなるかも
- deno_stdにもベンチマークのものがあるので、そこの兼ね合いはどうなるのか
- ファイルルックアップ機能もないので、こちらは廃止されそう
HTTPレスポンスの自動圧縮
- 以下の条件を満たす場合、DenoのネイティブHTTPサーバー(
std@0.130.0/http/server.ts
のserve
など)がHTTPレスポンスを自動圧縮するようになった- クライアントリクエストがgzipまたはbrotli圧縮のいずれかをサポート
- 圧縮可能なContent-Typeであること
- レスポンスが20バイト以上
- 圧縮後は、
Content-Encoding
ヘッダーを設定してエンコーディングを反映 Vary
ヘッダーを調整しレスポンスに影響を与えたリクエストヘッダを追加
- RyanさんとKitsonさんが、社内に導入されたペアプロ制度でランダムにペアを組んで実施した
- 趣旨は特になくノリでやったら上手くいったので、そのまま載った
- Deno processで圧縮してる
- これがベストプラクティスなのかはちょっとわからない
deno test --trace-ops
Deno.test
でリソースリーク検出時のエラー内容が改善される- 改善した結果パフォーマンスに影響が出たので、オプトインになった
- Deno自体のCIが低速化した
Deno.test
で動いているテストは全体ではないので、Deno.test
で動いている範囲は倍以上遅くなっている- パフォーマンスインパクトが大きかった
- Denoのテストの数が多いので、通常のプロジェクトであれば指定していいのでは?
Deno.connect
のAPIが変更
- 今までは
Deno.Conn
というオブジェクトを返していた transport: "tcp"
を指定するとDeno.TcpConn
、transport: "unix"
を指定するとDeno.UnixConn
が返ってくるように- Deno.Connに定義されていた
setNoDelay()
やsetKeepAlive()
はDeno.TcpConn
に移動 - ネットワークではないUNIXとの区別がつくようになった
transport: "unix"
をDockerと通信するために利用しているプロジェクトはある
Deno.listenTls
でcert
とkey
オプションがサポート
- 元々存在していた
certFile
とkeyFile
は非推奨化 - より柔軟になった
connectTls
などでは既に実装されていたが、listenTls
だけファイルパスで受け取っていた
パフォーマンス改善
- Op(という命令単位)の呼び出しが最大で60%程度まで高速化
atob
/btoa
も最大20倍ほど改善された- Rustの世界のものを使いたいときはOpというものを発行し、なんらかの副作用を起こす
- OpをCallするにはJavaScriptの世界から送るが、どうしてもオーバーヘッドが出る
- それが今回60%速くなった
- GoogleのFlatBuffersというプロトコルをまず使っていた
- FlatBuffersが速くないのでJSONでやっていた時期があった
- V8のValueのタスクをシリアライズして送ったほうが速いとなった
- そこからserde_v8が生まれた
- Sendという関数にいろんなタイプのOpを送っていた
- SendでOpのタイプを切り分けていた
- Sendが大きく、V8的に最適化できずにボトルネックになっていた
- Sendだけで処理するんじゃなくて、一個一個専用のSend関数を自動生成させるのをRustで作ることにした
- このコード生成を実施すれば速くなるのでは? と思ってやったら実際速くなった
- エンジンとどうやってつなぐか、という本質に近い部分でパラダイムシフトがあって、改善につながった
- リリースではそこらへんの歴史が語りきれていないので、どこかで記事出したい
atob
/btoa
の改善のきっかけはbunの作者であるJarredさんのツイート- Denoは改善すると6.5から7msになるよってAaronさんが言って、Jarredさんが更に速くして返してきた
- 最終的に3.5msになったよってAaronさんが言ってた
- JarredさんのDenoパフォーマンスへの言及でDenoにIssueが立って、パフォーマンス改善に繋がる好循環がある
TypeScriptがv4.5.2
からv4.6.2
へアップデート
Crypto.randomUUID()
がDOMに入ったらしい
deno.json(c)でimportMapオプションがサポート
- importMapを
deno.json(c)
に指定できるようになった
Deno.upgradeHttp()
が追加
- 途中からWebSocketに変える
- HTTPベースのプロトコル
- 内部的には明確な用途がある
- Nodeには同じ機能があるらしい
- 途中からWebsocketにするというViteがしてるらしい
- Node互換モードでのViteサポートが目的
- HTTPハイジャッキングというのがそれ
AbortSignal.timeout()
が実装
- 時間をミリ秒単位で指定すると、指定時間後にタイムアウトになる。
setTimeout
の代わりのように使えるAbortController
とsetTimeout
でやろうとするとゴチャゴチャするところを、少なく書ける- deadlineというユーティリティがあるが、不要になるかも(TODO: 探しても見当たらないのでPRなければ消す)
deno_std
Web Streams APIへの段階的移行
- 多くのdeno_stdが
Deno.Writer
/Deno.Reader
といったGoスタイルで実施されていた - それらを徐々にWeb Streams APIに移行していく
- 進捗はIssueにまとめられている
- Goのスタイルがシンプルで今まで回っていた
fetch
など、Web APIの潮流としてWebの一部で外せないものという捉え方になり、それに合わせた- GoのAPIスタイルが好きだった人にとってはデメリット
- RyanさんもGoスタイルが好き
- Web Streamは嫌いだが、Web Streamに寄せるということも言っている
dotenv
モジュールが追加
- PRを作った人はサードパーティモジュール制作者本人
- サードパーティと特に変わらず、お作法に合わせた修正が入っている
- 制作者の提案当初、Bartekさんがフォーマットとリンティングの修正のみで大丈夫そうという話だった
- いざそのままPR投げたら、ディレクトリ構造の関係でメチャクチャ指摘が出てきた
- 制作者は指摘にすべて対応してくれた、ありがたい
deno_std/node
の改善
- node-mysql2パッケージがある程度動くようになった模様
- deno_stdのリポジトリにexampleがある
- MySQLが内部的に持っている暗号化処理に互換性を持った
- DenoのAPIを実装することはできなかった
- DenoのcryptoはWeb Crypto APIベース
- 公開鍵暗号を使おうとするとasyncになる
- Nodeのcryptoはsync
- crypto-browserifyのpublicEncryptを参考に実装した
- webpackが内部的に使ってる
- pure jsでshimを実装している部分があり、そこを持ってきた
- 持ってきたと言っても依存関係が多かったので、そこを解決して実装
- child_processを実装する場合、DenoにないのでDeno APIを増やすしかない
- Node APIがそもそも多いので、まだまだ時間かかりそう
deno.landがNode.jsからDenoへ移行
- Next.js/TailwindCSS/VercelからFresh/Twind/Deno Deployに移行
- crowlKatsさんがやりきってくれた
- ほぼ全リライト
- Freshの構造はNext.jsと互換性があるので、そこまで変更点は大きくない
- TwindもTailwindの互換性を目指しているところがあるので、変更点は大きくない
- いいリライト事例になったのでは
FreshでIsland architectureが実装
- 部分的ハイドレーションでWebサイトを構築するIsland architectureで実装された
- ディレクトリ構造の見直しや
useData()
や<Suspence>
などの削除も行われた<Suspence>
は再度追加予定とのこと
- カスタムエレメントとか使って分割とかやってる
- Island architectureはAstroが一番最初にやってるはず
- Next.jsが採用すれば大きく普及するかも(Astro自体があまりメジャーなものではないので)
Remix v1.2.0での実験的なDenoサポート
yarn create remix --template deno-ts
でDenoのテンプレートが構築される
oakのNode.jsサポート
- dntを利用してoakがNode.jsをサポート
@oakserver/oak
という名称でnpmにパブリッシュされている- 現在は10.3.0と10.4.0、10.5.0がリリース済み
- Deno公式ブログに解説記事が公開されている
- dntはDenoの開発環境でNode.jsモジュールを開発できる
仕様への提案の仕方について
- 1つのPRに5〜6個も破壊的変更が入ったものを出した場合、議論が進まないので良くない
- 1つずつなら議論も進んだかもしれない
Node学園の話
- ガバナンスの話が面白かった
- Denoは作者が権力を持っていて、優しい終身の独裁者(BDFL)という権力構造になっている
- Node.jsは最初の数年はBDFLだったが、Open governance modelという民主主義に移行した
- 進み方としては特色が出る
- 独裁者がいると、間違うかもしれないけど決断力が高い
- Open governance modelはすごい方向性を変えるという決断はできないが、変な方向にいく可能性も低くなる
参考資料
上記をまとめる際に眺め、かつ上記の中に含められなかった資料です。
名前だけ掠ってて関係ない資料もあるかと思いますが、まとめる作業の可視化として残しています。
読まなくて大丈夫です。
- Accept-Encoding - HTTP | MDN
- HTTP Server APIs | Manual | Deno
- connect() - Unix, Linux System Call
- deno::Op - Rust
- FlatBuffers: Use in Rust
- denosaurs/deno_json_op: 📋 A macro for easing the development of deno plugins
- Overview · Serde
- Partial Hydration in Astro 🚀 Astro Documentation
- Islands Architecture - JASON Format
- Architecture | fresh docs
- lucacasonato/fresh: Preact, but super edgy
- Understanding open source governance models
- Introducing the Open Governance Network Model