Denoでは、新機能の導入がgithubのissueやdiscussionで議論されています。
最終的にどんな機能が導入されるかについてはコアチームの決定次第ですが、導入されそうなものを選んでまとめてみました。
3か月以内に予定されている変更
https://github.com/denoland/deno/issues/11168 に掲載されています。
ネイティブHTTPサーバーの導入
従来JS側で実装されていたサーバーがRustで書き直されます。
正確には、Rust製HTTPサーバーであるhyperを使うようになります。
この変更により、HTTPサーバーの処理速度がNode.jsを上回ります。
ベンチマークを見てみると、確かにNode.jsのHTTPサーバーのスループットがDenoネイティブHTTPサーバーのスループットを上回ってますね。
もともとNode.jsはRyan DahlのC10K問題(HTTPサーバーの処理能力の問題)に対する答えとして作られました。その性能を同じ作者によって作られたDenoが超えていくのは、10年越しの伏線回収みたいで激アツですね。
8月10日公開のv1.13.0で正式リリースされる予定です。それまでの間は--unstable
フラグを付けて試すことが出来ます。
また、標準ライブラリのHTTPサーバーや、Deno向けサーバーサイドフレームワークの対応も進められています。
関連PR: #9935
FFIの導入
FFIが導入されます。C言語などの他言語のコードを、Denoから呼び出すことが可能になります。
似たような機能としてネイティブプラグインがありましたが、これは削除されます。
FFIを使用するには--allow-ffi
フラグを指定する必要があります。これはFFIに対してファイルアクセスなどの細かいパーミッション制御ができないからです。
関連 #11152
標準ライブラリに「collection」モジュールが登場
標準ライブラリに、新しく「collection」モジュールが登場します。
主に配列・オブジェクト操作系の関数が収録されています。
既に利用可能になっています。
https://deno.land/std/collections
新しいテストAPI
Denoにはテスターが搭載されています。Node.jsで言うjestやjasmineのようなものです。
今まではDeno.test
というAPIを使用してテストを定義していましたが、このテストAPIを拡張して、並列テスト、テストの階層化が可能になります。
現在検討されているAPIは以下のようなものです。Deno.test
に与えるコールバック関数の引数を使って、サブテストを実行することが可能になります。
Deno.test("group with subgroup", async (t) => {
await t.run("subgroup", async (t) => {
await t.run("case 1", () => {});
await t.run("case 2", () => {});
});
});
また、テストを階層化することで「全てのテストの前に○○を実行する」「全てのテストの後に○○を実行する」のような事が可能になります。
関連discussion: #10771
新しいサブプロセスAPI
従来のサブプロセスAPIはDeno.run
でした。Deno.run
APIはゾンビプロセスを生成する可能性があることや、stdinやstdoutのハンドリングを行う必要があるDeno.run
の使用法が直感的でないことや、生成したサブプロセスをデタッチモードにできないことから、直感的な新しいAPIの導入が検討されていました。
現在、単純で使いやすいAPIと、低レベルで複雑な設定が可能なAPIの導入が検討されています。
ユースケースとしては、
- 「コマンドを実行して出力を受け取るだけ」→単純なAPI
- 「通信しながら長時間実行するサブプロセス」→複雑なAPI
が想定されているようです。
関連issue: #11016
deno docのリファクタリング
現在、deno doc
コマンドはターミナル上への出力とjson出力のみサポートされており、HTML出力を利用するには https://doc.deno.land/ を使うしかありませんでした。
deno docのリファクタリングによって、ローカルでのHTML生成を可能にすると共に、wasm化してランタイム上で動かせるようになる見込みです。
関連issue: deno_doc#111
プロセス間のBroadcastChannel
BroadcastChannel APIはブラウザのタブやウィンドウ、Worker間で通信するためのAPIです。DenoではWorker間での通信に利用されています。
このBroadcastChannel APIで、Denoプロセス間の通信が可能になるようです。
現状、プロセス間通信を既存のAPIを使って実装する場合、web socketサーバーや標準入出力などの低レベルなAPIを使う必要があると思います。
これがnew BroadcastChannel()
だけで可能になるのは、結構すごい事なのではないでしょうか。
関連issue: #10750
deno実行ファイルへの署名
これはタイトル通りですね。deno.exe本体に対してデジタル署名を行うようです。
関連issue: #575
SSL証明書エラーを無視する機能
現在、fetch()
を使ってSSL証明書エラーがあるサイトと通信することはできません。
SSL証明書エラーがあるサイトと通信することはセキュリティ上の観点から望ましくないという事で、新しい実行時フラグ(--allow-xxx
のようなもの)を導入し、そのフラグが有効な時だけ通信可能になるようです。
この機能の導入については2018年から議論されていて、やっと導入されるようです。
関連issue: #1371
--prompt
フラグをデフォルトで有効化する
Denoでは、ファイルの読み書きやインターネット接続を行いたい場合に--allow-xxx
のようなフラグを付与する必要があります。
フラグを付与しなかった場合は、エラーが出て実行が終了します。
ここで--prompt
フラグを渡して実行すると、エラーを出す代わりに、アクセス許可を求めるプロンプトが表示され、プログラムの実行を継続することができます。
現在検討されているのは、--prompt
フラグの挙動をデフォルトにしようという案です。
ユーザー入力が求められない環境向けに、--no-prompt
というフラグも導入される予定です。
関連issue: #10183
デフォルトでTypescriptの型チェックをスキップ
これはかなり賛否のある機能です。
DenoはTypeScriptを実行できるのですが、そのまま実行しているわけではなく、内部で自動的にJavaScriptへ変換した上で実行しています。変換には、tsc(型チェックを行う低速なトランスパイラ)か、swc(型チェックを行わない高速なrust製トランスパイラ)が利用されています。
変換時に型チェックを行うかどうかは、--no-check
フラグの有無で選択できます。
現在、デフォルトでは型チェックが行われていますが、これを変更して、デフォルトで型チェックをスキップするようになります。
型チェックありで実行したい時には--check
フラグを渡すことになります。
賛成派の意見
- 初心者にとって型チェックは煩わしいだけ
- ほとんどの人はIDEを使用しているので、型エラーがある場合はエディタ上に表示される
- 型チェックにはパフォーマンスの問題がある
否定派の意見
- (JSではなく)TypeScriptを書いている以上、型チェックされることを期待している
- 正しいコードを書いていれば型エラーは発生しない
- 型チェックをする前提でCIが組まれている場合、期待通りに動かなくなる
- swcにはまだバグがある
当初v1.12.0で導入される予定でしたが、反対意見が多く、v1.13.0に延期されました。破壊的な変更であり、v2.0まで導入を待つべきだという意見もあります。
個人的には否定派です。(// @ts-nocheck
や// @ts-check
の意味が無くなるので)
関連discussion: #8549
関連issue: #11340
メタデータファイル
実行時に毎回--allow-readとか書くのは面倒だということで、設定ファイルの導入が検討されています。
velociraptorというサードパーティ製ツールに近いのかなと思います。
package.json
とは違い、プログラムのエントリポイントでのみ使われるという雰囲気です。
書き方的に、まだ「検討を進める」という段階にあるっぽいですね。
まずはdeno lint
やdeno fmt
の設定ファイルとして導入するようです。
関連issue: #3179
deno deploy関連
deno deployは、Cloudflare WorkersのようなエッジCDNワーカーです。
多数の箇所に分散配置されたサーバーでJavaScriptとTypeScriptを実行することが可能で、webサイトのホスティングなどを行うことが出来ます。
年内の正式公開までの間に、いくつか新機能の導入が予告されています。
Denoランタイムとの互換性向上
これまでdeno deployはdenoランタイムと互換性が無く、ローカルで実行するにはdeployctl
というツールが必要でした。
今後その制限がなくなり、deno向けのコードがdeno deployでそのまま動くようになります!
これにより、Deno向けサーバーフレームワークがdeno deployでも利用可能になることが考えられます。
また、deno deploy上でDeno.readFile()
がgithubリポジトリのファイルを読み込み可能とすることで、denoランタイムとの互換性を向上させるといった事も考えられているようです。
複数エッジ間の通信
BroadcastChannel APIはブラウザのタブやウィンドウ、Worker間で通信するためのAPIです。
deno deployでは、分散配置されたサーバー(=エッジ)間の通信を、このAPIを使って行うことができます。
用途としては、リアルタイムなチャットツールなどが思い浮かびます。
今後予定されている変更
Denoリポジトリのdiscussionの中に、「デザインミーティング」という名前でコアチームの議事録が掲載されています。
- https://github.com/denoland/deno/discussions/11363
- https://github.com/denoland/deno/discussions/11364
- https://github.com/denoland/deno/discussions/11365
- https://github.com/denoland/deno/discussions/11420
- https://github.com/denoland/deno/discussions/11497
コアチーム内で今後のAPI設計についての方針が話し合われているようです。その中から、導入されそうな新機能を紹介したいと思います。
JSONインポート
TypeScriptの対応待ちです。10月のTypeScript4.5で対応される見込みであり、Denoに導入されるのはその後です。
Deno.emit()の強化
Deno.emit()
はTypeScriptコードをJavaScriptコードに変換する関数です。
Denoでは拡張子(.ts
, .js
)付きのimport文が使われますが、Deno.emit()
は変換の際にimport文の拡張子を変更しません。
変換後のコードをそのまま動かせるように、impot文の拡張子を.ts
から.js
に自動で変えるというオプションが検討されています。
関連issue: #4538
deno info / deno doc サブコマンドをランタイムAPIから使用可能にする
Deno.info()
やDeno.doc()
のような関数を導入して、deno info
/deno doc
コマンドをランタイムから利用できるようにすることが検討されています。
現状でもサブプロセスを使ってDeno.run({cmd: ['deno', 'info']})
とすれば実行可能ですが、これは--allow-run
フラグを必要とします。
--allow-run
フラグを指定すると、Deno.run()
を使用してDenoに任意のパーミッションを付与することが可能であり、必要以上に大きな権限を与えることになってしまいます。
--allow-run
フラグ無しでもサブコマンドの実行結果を得られるようにするため、ランタイムAPIへの導入が検討されています。
関連PR: #10758
FileSystemAccess API
Chromeなどに導入されているFileSystemAccess Web APIを、Denoにも導入しようとする動きがあります。
Denoの方針としては、
- Web APIで対応できるものは極力Web APIで対応
- Web APIで対応できないものは
Deno.xxx
の形でAPIを提供する
という事になっています。
現在、ファイルアクセス系の関数はDeno.xxx
の下にありますが、FileSystemAccess APIのサポートに切り替えていくことが検討されています。
関連issue: #11018
JSXファクトリ関数のデフォルト値を変更
JSXはトランスパイル時に関数に書きかえられます。どの関数に書き換えられるのかはtsconfig.json
で設定できます。
現在、tsconfigに何も指定しなかった場合はReact.createElement
という関数にトランスパイルされています。これはReactが使われているNode.jsでは便利ですが、Denoにとってはあまり意味がありません。
ということで、このデフォルト値をh
に変更することが検討されています。
関連issue: #11186
Web USB API
Web USB APIが導入予定です。
Web USB APIはJavaScriptからUSB機器の操作を可能にするAPIです。PCに繋いだICカードリーダやマイクロコントローラーなどの機器を操作することができます。
実装は完了していて、CI環境の整備を待っているようです。
関連PR: #10912
indexed DB
既にlocalStorageとsessionStorageが導入済ですが、これに加えてindexed DBもサポートされる見込みです。
ランタイムにデータベースが組み込まれていてすぐに利用可能というのは、他のランタイムに対してかなりのアドバンテージだと思います。導入が待ち遠しいです。
関連issue: #1699
v2.0で導入される破壊的変更
Denoではマイナーバージョンアップでの破壊的変更を避けており、2.0へのメジャーバージョンアップ時に破壊的変更が入ります。
2.0へのバージョンアップの時期ですが、「破壊的変更の数が溜まったら」という事になっています。
2.0で予定されている破壊的変更の一覧は、こちらで見ることが出来ます。
長くなったのでこの記事では取り上げませんが、いつか一つずつ詳しく紹介出来たらなと思います。
感想
Web USBやFileSystemAccessなどのAPIは、一部では「危険なJavaScript」と称され忌避されています。
しかし、実態としては、Denoやブラウザにおいて手動でパーミッションを付与した時にのみ有効化されるものです。
もし、Electronのようなネイティブアプリに全ての「特権」を付与するか、ブラウザのサンドボックス内で何の権限も付与されないかの2通りしか無かったとします。これでは、USBのような特定の権限だけが欲しい時にもファイルシステムへのアクセス権を付与するしかないという事であり、セキュリティの観点から安全とは言えません。
Denoやブラウザのような、サンドボックスを基本として必要な部分のみ特権を与えるセキュリティモデルが広まると嬉しいな、と思いました。