TechFeed Experts Night Pick up

進化するDeno in 2022 ~TechFeed Experts Night#8講演より

本記事は、2022年11月に開催された「TechFeed Experts Night#8 ~ JavaScriptランタイム戦争最前線」のセッション書き起こし記事「進化するDeno in 2022 - npm互換性、パフォーマンス、開発者体験の向上など」を転載したものです。オリジナルはTechFeedをご覧ください。

よろしくお願いします。Denoの最近の動向について話していきます。

さっそくですが、2022年6月にDenoは資金調達をしました。2100万ドル(約29億3600万円)という、この界隈ではかなり大きめな調達だったのでざわざわしたりしました。

Deno資金調達

7月にはBunというけっこう有力なライバル企業が登場してきて、Deno社内はざわざわしたりしていました。

Bunというライバル登場

そして、8月にnpm互換性をリリースして、これはかなり反響が大きかったです。

8月npm互換性リリース

10月には「Deno Offsite」というイベントが開催されて、⁠Deno社員が初めてオフラインで会う!」みたいなことが起こったりしました。

10月Deno Offsite

そんなイベント盛りだくさんだった2022年でしたが、2022年のDenoの変化のキーとなったブログポストというものがありまして、それが8月に掲載されたBig Changes Ahead for Denoです。今日はおもにこの話をしようと思います。

8月Big Changes Ahead for Deno

ここでちょっと簡単に自己紹介なんですけど、⁠ひのさわ」といいます。Twitterは@kt3kというアカウントでやっています。2009年からWebエンジニアをしていて、2011年からDenoの開発会社であるDeno Landのソフトウェアエンジニアとして働いています。Deno歴、Denoとの関わりで言うと、プロジェクト初期の2018年からOSSとしてのDenoにずっとコントリビュートしていて、2020年末ごろに作者に誘われてDeno Landに転職しました。現在はフルタイムでDenoとDeno Deployを開発しています。直近で言うとかなりDeno側の比率が自分は多くなっています。

自己紹介

本日のアジェンダです。Deno全体のおさらいをして、さっき言った「Big Changes Ahead for Deno」の話をします。

本日のアジェンダ

開発者体験にフォーカスしたJSランタイム

知っているという人もいると思いますがもう一度おさらいすると、Denoとは開発者体験(DX)にフォーカスしたJavaScript runtimeです。

Denoとは開発者体験(DX)にフォーカスしたJavaScript runtime

どういう点がDXにフォーカスしているのかというと、ひとつにはビルトイン開発ツールがあります。⁠deno lint」⁠deno fmt」⁠deno test」のようなツールがビルトインで実装されていて、Nodeで言う「prettier」⁠eslint」⁠jest」⁠vitest」に対応するものです。サードパーティに頼らなくてもこういった基本的な開発ツールが全部手元に揃っているという特徴があります。

ビルトイン開発ツール

ほかには、TypeScriptビルトインというものがあります。NodeでTypeScriptを利用するとなると、TypeScript自体をインストールして、TSやTSに対応するバンドルアダプタをインストールして…とインストールが多く、さらにtsconfigでcompiler optionsを書かなければなりませんが、こういった設定が不要なので便利です。

TypeScriptビルトイン

また、モジュール機構がとても整理されています。NodeやBunでは、CJSかESMかという話があるんですね。モジュールモードかスクリプトモードかで言語としても微妙に違うところがあって、その結果、.cjs、.mjs、それに対応したTSの.cts、.mtsといった拡張子があったり、パッケージなので"type": "module|commonjs"みたいなことを書いたりという、かなり複雑なものがあるんですけど、Denoだと整理されてESM onlyになっています。その結果として、.tsと.jsしかありません。

モジュール機構が整理されている

先日、こういうミームをTwitterに流してみたのですが、わりと多くの人が同意してくれました。.jsや.tsだけで書きたいというのは皆さん思っているようです。

.jsや.tsだけで書きたい

強固なセキュリティと豊富なWeb API

DenoのDXでほかに良いところとしては、サプライチェーン攻撃に対する防御機構がすでにビルトインされていることが挙げられます。Nodeも作ろうとしているという話がありましたが、まだできてないようです。たとえばここで deno run という実行コマンドを打って実行したときに、サプライチェーン攻撃が含まれているとします。たとえばgoogle.evilserver.comにクレデンシャルを盗んで送る攻撃が仕込まれてしまったときに、Denoはこのような感じで「そこにアクセスしていいですか?」と聞いてきます。ここでdenyを選べば、何も盗まれずに済みます。

サプライチェーン攻撃に対する防御機構がビルトイン

これをどうやって実現しているかというと、内部でV8のサンドボックス機構というものをうまく活用しています。詳細は公式ドキュメントの「Permissions」ページを参照してください。

内部でV8のサンドボックス機構を活用

また、DenoのDXの良い点として、Web互換APIがたくさんあります。fetch()とかTypedArrayとかprompt()とか、ほんの一例ですがこのようなものがあります。

Web互換API

ブラウザで使える同じ知識でDenoのコードを書けるので、よけいなAPIを覚えなくてよいということですね。すべてのリストがlist of every web APIというブログ記事に載っているので、よければ見てみてください。

ブラウザで使える同じ知識でDenoのコードを書ける

このような感じで、DenoはJS runtimeのあるべき姿というのを模索しているのかなと思っています。

Denoの3つの「Big Changes」

さて、今日の本題の「Big Changes Ahead for Deno」の話に入っていこうかと思います。Bunが出た話にも少し関係するのですが、⁠今までDXにフォーカスしてDenoを作ってきたけどちょっと変えなきゃいけないことがあるよね」ということで、どういう点を変えていくのかという思想のようなものを8月に発表しました。

Big Changes Ahead for Deno

その中で、今後起こる3つの変化を記載しています。1つ目が「npm互換性をやります」という話です。npmを何らかの形でDenoから使えるようにするということをブログ記事の中で言いました。この時点ではまだどういうふうに互換されるのかというのは決まっていませんでした。

2つ目の軸として「パフォーマンスを向上します」と宣言しました。この記事の時点でも、DenoのたとえばHTTPのパフォーマンスは、Nodeと比べて互角か若干優位ぐらいのパフォーマンスが出ていたのですが、そこで満足せずにもっとパフォーマンスを上げていく、そして最も速いJS runtimeであることを常に目指すということを表明しました。

3つ目としては今までの延長線ですが、⁠DXをもっと向上していきます。とくにモジュールの検索性にフォーカスして機能拡張していきます」ということを言いました。

これらを宣言した結果として、社内ではこの3つにかなりフォーカスした作業をすることになりました。それがどういう結果になったかというのを見ていきましょう。

Denoに今後起こる3つの変化

npm互換性 - npm: specifier

npm互換性については、8月に入れると宣言して、ちょうど今週月曜(11/14)にnpm: specifierというものを正式に導入することになりました(参考ブログ)。

このサンプルのように npm:expressという形でnpmモジュール名をnpm:という独自のURLのようなものからインポートできます。このサンプルで言うと、import express from "npm:express";でnpmモジュールが自動的にダウンロードされて、さらに展開されてインポートされて、npmモジュールのexpressがDenoの中で動きます。このサンプルを最新版のDenoで実行すると、ポート3000でサーバが立ち上がってHello World!を表示できるようになりました。

npm互換性

ちなみに自分はこの辺の作業を主にやっていて、とくにspecifier自体ではなく、npm互換の中で動くNode.jsのshimのAPIを実装し直す作業を主にしています。Deno標準モジュールの中のnode/というディレクトリがあって、そこの下にNode.jsのlib/というものがあるんですけど、それをひたすらAPIとして移植をしています。

npm互換の中で動くNode.jsのshimのAPIを実装し直す作業を担当

パフォーマンス向上 - すでに高速だったDenoをさらにチューン

2つ目の軸のパフォーマンス向上については、このためにDenoの社内でパフォーマンスだけを専門的にやるチームが発足しました。その成果として、Deno.serveという新しいAPIを作ることになりました。社内でのコードネームは「Flash」と呼ばれており、開発中です。すでに既存のHTTPであるDeno.serveHttpより圧倒的に速いパフォーマンスが出ています。

パフォーマンス向上

新しいホームページでは、HTTP1.1でのパフォーマンスをwrkというベンチマークツールで1秒間に何リクエスト処理できるか(リクエスト/s)というベンチマークを取っています。Denoでは1秒に200kリクエスト処理できて、Nodeでは90kになっています。ただの「Hello World」のHTTPサーバだとNodeの倍ぐらいパフォーマンスがすでに出るようになっています。ちなみにBunは、ここに載せていませんが175kちょいなので、⁠Hello World」のHTTPでは今はDenoのほうがパフォーマンスが良いという状態になっています。

Denoでは1秒に200kリクエストを処理、Nodeでは90k

DX向上 - 検索性の改善を

3つ目の軸のDX向上ですが、まずどうしてここにフォーカスするという形になったのかというと、Denoはモジュールの検索性がすごく悪いという問題がありました。npmではnpm自体がnpm searchのようなサービスをマージして持っていて、コードの人気度やクオリティといったいろいろな軸でindexingしてあるなど、モジュールが適切に検索できる工夫がされています。それがnpmの強さのひとつでもあるのですが、Denoはそこにかなり遅れを取っていたということがありました。

例として、Deno界で一番有名な「oak」というWebフレームワークをDenoのレジストリで検索すると、なぜかoakではないものが1ページ目の10エントリ分を占めてしまって、oakは2ページ目の一番上に出てくるといった残念な状況になっていました。

検索性の改善

それを8月以降に改善して、今では人気順というものを加味できるようになりました。今では普通にoakを検索したらoakが一番上にくるようになっています。

人気順を加味できるように

ここにとどまらず、DX向上について、シンボル検索というものを実装しました。シンボル検索というのはモジュール単位の検索ではなく、exportされているすべてのシンボルを検索の対象として横断的に検索するものです。モジュール検索のようにサードパーティだけを検索するのではなく、本体のAPI、標準モジュールのAPI、サードパーティのAPIのexportされているすべてのシンボルを混ぜて、その中から横断的に検索できます。これはもう実装されています。

シンボル検索を実装

このようにDenoのホームページの一番上からこの検索ボックスを表示できて、たとえばassertと入力すると「シンボル」タブの中で「assert」という標準のAPIや、⁠assertThrows」⁠assertSnapshot」などサードパーティを含めた「assert*」というAPIを全部表示できます。この検索はたぶんNodeでは難しくて、最初からESMに絞って、exportされているものが静的に全部解析できるDenoのシステムならではの機能かなと思います。

Denoホームページから検索ボックスを表示

このようにBig Changesで3つの軸を出したことで、Denoの中でプライオリティがかなり明確化されて、目的意識を持った深い開発ができるようになったかなと思っています。

まとめ

まとめですが、DenoはDXにフォーカスしたJavaScript runtimeです。現在のDenoは「パフォーマンス」⁠npm互換」⁠開発体験向上」の3つの軸で開発が進んでいます。

まとめ

ちょっと早いですが以上になります。ありがとうございました。

おすすめ記事

記事・ニュース一覧