Deno 1.16が来たぞ
2021年11月9日にDeno 1.16がリリースされました。
本記事では、上記のリリースノートの内容をざっと紹介していきます。
-
fetch
がfile URLをサポートした - React17のJSX変換がサポートされた
- Signal Listener APIが追加された
- Error.causeがコンソールに表示されるようになった
- TLS接続のハンドシェイクを明示的に実行できるようになった
- Web Streams APIに機能が追加された
- Deno.startTlsが安定化された
- Per-test permissionsが安定化した
- localStorageの使用に
--location
が不要になった - AbortSignalに理由が指定できるようになった
-
dnt
がリリースされた - V8が9.7にバージョンアップした
fetch
がfile URLをサポートした
fetch
メソッドの引数にファイルパスを取れるようになりました。
import.meta.url
を基準とした相対指定でファイルを読み込む場合などに役立つとのことです。
ファイル読み込みなので、実行には--allow-read
オプションが必要です。
ファイルフェッチはWeb仕様では定義されていないため、Firefoxの実装が参考にされています。
最も単純なサンプルはこちら。
const resp = await fetch("file:///etc/hosts");
const text = await resp.text();
console.log(text);
また、次のコードは記事の例を元にしたサーバーでの使用例で、従来のreadTextFile
もコメントで併記してみました。
fetch
はファイルをチャンク単位で読み込むので、メモリ使用量的に有利になるようです。
import { serve } from "https://deno.land/std/http/server.ts";
const addr = ":8080";
console.log(`HTTP server listening on http://localhost${addr}`)
serve(async (request: Request) => {
const { href, origin, host, pathname } = new URL(request.url);
console.log({ href, origin, host, pathname });
// const index = await Deno.readTextFile("./static/index.html");
const resp = await fetch(new URL("./static/index.html", import.meta.url));
const index = resp.body;
return new Response(index, {
headers: { "content-type": "text/html; charset=utf-8" },
});
}, { addr });
このサンプルでは"./static/index.html"
を表示させています。
readTextFile
に相対パスを渡す場合はDeno.cwd()
が基準となりますが、new URL()
でファイルパスを生成する場合は第2引数のパスが基準となるので、同じファイルを読み込む場合でも、パスの指定が異なる可能性があることに注意してください。
さらに、以下の点が注意点として挙げられています。
- ファイルが見つからない場合、
fetch
から返されたPromise
はTypeError
で失敗(reject)となります。 - ディレクトリが指定された場合も、同様に
TypeError
で失敗します。 - レスポンスに
content-length
ヘッダーが設定されていません。応答本文がストリームではなく、正確な長さを事前に知ることができないためです。 - レスポンスに
content-type
ヘッダーが設定されていません。ファイル拡張子からコンテンツタイプを取得する方法として、media_typesモジュールが紹介されています。
React17のJSX変換がサポートされた
React17で導入されたJSXの変換方式をDenoでもサポートするようになります。
以下の2つの利用方法があります。
1: jsx
/tsx
ファイルで@jsxImportSource
を宣言する
/** @jsxImportSource https://esm.sh/preact */
export Welcome({ name }) {
return (
<div>
<h1>Welcome {name}</h1>
</div>
);
}
2: Configuration fileを使う
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "https://esm.sh/preact"
}
}
Signal Listener APIが追加された
新たなunstable
APIとして、Deno.addSignalListener()
とDeno.removeSignalListener()
が追加されました。
プロセスが特定のシグナルを受け取ったときに実行する関数を追加・除去するAPIです。
以下のコードで試すことができます。
const listener = () => {
console.log("SIGINT!");
};
console.log("Start listening to SIGINT!");
Deno.addSignalListener("SIGINT", listener);
// Wait 3 seconds
await new Promise((resolve) => setTimeout(resolve, 3000));
console.log("Stop listening to SIGINT!");
Deno.removeSignalListener("SIGINT", listener);
// Wait 3 seconds
await new Promise((resolve) => setTimeout(resolve, 3000));
console.log("End of process!");
これをdeno run --unstable signal_listener_sample.ts
で実行し、実行中にCtrl+c
でSIGINT
を送ってみると挙動が確認できると思います。
試してみるとわかりますが、一度addSignalListener
すると、本来の挙動(Ctrl+c
でプロセス中断)に戻りません。
これは、内部で使用されているtokio::signal
というRustモジュールの抱えている問題とのことで、留意が必要そうです。
また、unstable docによれば、いまのところWindowsでは使えないようです。
Error.causeがコンソールに表示されるようになった
1.13でError
オブジェクトにcause
プロパティが追加されていました。
これがコンソールに出力されるようになり、デバッグに使いやすくなりました。
こんな感じのコードで確認できます。
try {
throw new Error("main error", { cause: new TypeError("caused by this") });
} catch (e) {
console.log(e);
}
TLS接続のハンドシェイクを明示的に実行できるようになった
これまでは、TLS接続で最初にデータを読み書きするとき、自動でハンドシェイクが実行されていました(ほとんどのユーザーはハンドシェイクの詳細を気にする必要がないため…とのこと)。
今回のリリースでDeno.TlsConn
にhandshake()
メソッドが追加され、TLSハンドシェイクを手動で実行できるようになりました。戻り値はハンドシェイクが完了するとresolve
するPromise
です。
Web Streams APIに機能が追加された
Web Streams APIに機能がいくつか追加されました。
-
ReadableStreamBYOBReader
がサポートされました。この「Bring-Your-Own-Buffer(BYOB)」リーダーは、開発者が提供したバッファに読み込むことで、通常(ReadableStreamDefaultReader
)と比較してコピーを最小限に抑えることができます。このAPIについてはMDNで詳しく紹介されています。 -
WritableStreamDefaultController.signal
がサポートされました。詳しくはexplainerをご覧ください。 -
ReadableStream.getIterator
が削除されました。このメソッドはDeno 1.7から非推奨となっており、どのブラウザでも実装されていませんでした。ReadableStream
にはAsyncIterable
が実装されているので、ストリームのイテレーションにはそちらの使用が推奨されています。
Deno.startTlsが安定化された
こちらもTLS関連の更新です。
Denoでは、TLSでサーバーに接続する方法として、以下のAPIがあります。
-
Deno.connectTls
: TCP接続を開いてすぐにTLSの通信を開始する -
Deno.startTls
:まず平文のTCP接続を作成し、データを交換してから、その上でTLSの通信を開始する
今回のリリースで、後者のstartTls
APIが安定化されました。
これにより、SMTPドライバが--unstable
不要で動作するようになり、その例としてpostgresモジュールが挙げられています。
Per-test permissionsが安定化した
Deno 1.10で、テスト毎にパーミッションを与えられる機能が追加されていました。
今回の1.16より、これが安定機能(--unstable
不要)になりました。
--location
が不要になった
localStorageの使用にこれまでのバージョンでは、localStorage APIの使用には起動時に--location
オプションの付与が必要でした。
今回のリリースで、--location
オプションを付けずに実行した場合もlocalStorage APIを使用できるになりました。
--location
オプションを付けない場合、ストレージバケットのキーが暗黙で設定されます。キーを明示的に設定したい場合は--location
フラグが必要です。
使用されるキーは以下のように設定されます。
-
--location
オプションを使用すると、そのオリジンが使用されます。つまり、ロケーションがhttp://example.com/a.ts
、http://example.com/b.ts
、http://example.com:80/
はすべて同じストレージを共有しますが、https://example.com/
は異なるストレージになります。 -
--location
の指定がなく、--config
で設定ファイルが指定されている場合は、その設定ファイルの絶対パスが使用されます。つまり、deno run --config deno.jsonc a.ts
とdeno run --config deno.jsonc b.ts
は同じストレージを共有しますが、deno run --config tsconfig.json a.ts
は異なるストレージになります。 -
--location
も--config
も指定されていない場合、メインモジュールの絶対パスが使用されます。 また、Deno REPLは、Deno.cwd()
をもとにメインモジュールを生成します。つまり、同じパスからREPLを複数回起動すると、同じストレージを共有します。
AbortSignalに理由が指定できるようになった
WHATWGがAbortSignalに理由を指定できるようにしたらしいのですが、これが速攻で取り込まれました。
本件のIssueを見ると、WHATWGのプルリクがマージされてから6時間くらいでDenoに取り込まれ、その翌日に今回のリリースという爆速対応。
@crawKatさんがやってくれたようです。
dnt
がリリースされた
これはDeno 1.16の中身ではないのですが、ブログで紹介されているので記載します。
1.15でNode.js互換モード(--compat
)が追加されました。
これに関連し、Denoモジュールをnpmパッケージに変換するdnt
というツールがリリースされています。
以下のような変換が行われるようです。
- Deno namespaceを使っている部分がdeno.nsを使うように変換される
- 型チェック実行後、
d.ts
ファイルを生成する - Deno用テストコードをNode.js用に変換し、さらにNode.js環境での実行確認を行う
ということで、一度設定して実行すれば、簡単にnpm moduleに変換できるとのことです。
例として、@kt3kさんのdeno_license_checkerが紹介されています。
V8が9.7にバージョンアップした
V8が9.7にバージョンアップしました。1.15の時点では9.5だったので、マイナーバージョンが2つ上がったことになります。
WebAssemblyの参照型がサポートされた
JavaScriptからの外部参照をWebAssemblyモジュールで使えるようになりました。
これはV8 9.6で入った機能とのことです。
findLast
およびfindLastIndex
が追加された
Array
とTypedArray
にfindLast
とfindLastIndex
が追加されました。
これに際し、同日リリースのstd@0.114.0にて、std/collections
に入っていた同名のメソッドはdeprecated
となっています。
おわりに
今回も盛りだくさんのリリースでした。
また、公式ブログで紹介されていない細かな調整も入っていますので、気になる方はGitHubのリリースページをご確認ください。
追記:11/11に修正版の1.16.1がリリースされました。
もうすぐDeno 2.0も来る…かな?
Discussion