Deno 1.11.0 がリリースされたので新機能や変更点の紹介
Copyright (c) 2018-2021 the Deno authors. MIT License.
日本時間の今日(2021 年 6 月 9 日)に Deno の v1.11.0 がリリースされました。
詳細なリリース内容は上記のリリースノートにまとまっていますが、ざっと紹介していきたいと思います。
- 公式 Docker イメージ
- Web Crypto API の実装が進む
-
fetch
を中断することができるように -
deno lint
が stable に -
deno compile
で動的インポートの部分的な対応 -
TextEncoderStream
とTextDecoderStream
がサポートされる -
BroadcastChannel
が実験的サポート - Deno LSP に様々な改良
-
Deno
名前空間のいくつかの API の引数が変更 - TypeScript 4.3
- Web Platform Tests の対応状況を可視化
1. 公式 Docker イメージ
これまでDenoはコミュニティによって管理されているDockerイメージしかありませんでしたが、ついに公式によるDockerイメージ提供が始まりました。
- Alpine Linux
- CentOS
- Debian (default)
- Distroless
- Ubuntu
$ docker run -it --init denoland/deno:1.11.0 repl
$ docker run -it --init --entrypoint sh denoland/deno:1.11.0
# 1. 1993番ポートをバインド
# 2. カレントワーキングディレクトリをコンテナ内の `/app` にマウント
# した上で、`--allow-run /app/main.ts` を起動
$ docker run -it --init -p 1993:1993 -v $PWD:/app denoland/deno:1.11.0 run --allow-net /app/main.ts
2. Web Crypto API の実装が進む
Web Crypto API への対応が進みました。Deno は 1.0 から crypto.getRandomValus()
をサポートしていましたが、今回のリリースではさらにハッシュ化および UUID 生成の API が追加されました。
以下のように、SubtleCrypto.digest
API によって sha-256、sha-384、sha-512、sha-1 のハッシュ化を行うことができます。
import { encodeToString } from "https://deno.land/std@0.97.0/encoding/hex.ts";
const data = new TextEncoder().encode("Deno 1.11 has been released!");
const digest = await crypto.subtle.digest("sha-256", data.buffer);
console.log("Digest:", encodeToString(new Uint8Array(digest)));
また、以下のように crypto.randomUUID()
API を使うことで、RFC 4122 に準拠した UUID v4 を生成することができるようにもなりました。
console.log("Random UUID:", crypto.randomUUID());
来月リリース予定の Deno 1.12 に向けて Web Crypto API の実装がさらに進んでいく予定です。
fetch
を中断することができるようになった
3. 例えば数秒待ってもレスポンスが返ってこないときなど、fetch
の実行を中断させたいときがあります。そのようなときに使える API として AbortSignal
が追加されました(例のごとく、Web 標準の API です)。
// まず `AbortController` インスタンスを生成する
// のちほど `fetch` を中断すべきタイミングで `AbortSignal` を発行する役割
const controller = new AbortController();
// `fetch` のタイムアウトを5秒後に設定する
// 実際のアプリでは、タイムアウトより前に処理が完了したら、タイムアウトを解除するなどする
setTimeout(() => controller.abort(), 5000);
// ある URL に対して `fetch` を実行し、そのときに `AbortController` から生成した `signal` を渡す
// リクエストの送信中、あるいはレスポンスヘッダの受信中にシグナルが発火したら、`fetch` は Reject となる
const response = await fetch("https://myslowapi.com/users", {
signal: controller.signal,
});
// レスポンスをパースする
// ここで、シグナルが発火するよりも前にこのパース処理も完了しなければならない、ということに注意
const users = await response.json();
リクエストはいかなるタイミングでも中断することができます。つまり、リクエストヘッダ送信中、リクエストボディ送信中、レスポンスヘッダ受信中、レスポンスボディ受信中、のいずれのタイミングでも中断することができるということです。
deno lint
が stable に
4. 2020 年 6 月にリリースされた Deno 1.1.0 で導入された Deno の組み込みリンター deno lint
ですが、これまでは「不安定」機能として提供されていました。まだ開発初期段階であり、様々なバグを含んでいる可能性があるということをユーザーに知らせるためです。
1 年経ち、コミュニティからの多数のフィードバックを受けてある程度安定的な機能を提供できるようになったことから、ついに "stable" に昇格しました。
"stable" とはいえ、今後も必要に応じて lint ルールの追加や削除は行われる予定です。
deno compile
で動的インポートの部分的な対応
5. v1.6.0 で追加された単一の実行バイナリを生成する deno compile
コマンドですが、さまざまな機能的制約を含んでいます。制約のうち特に改善が求められていたのが、動的インポートのサポートです。そこで今回のリリースでは、Data URI による動的インポートへのサポートが追加されました。これにより、ローカル・リモート問わずソースファイルを読み込むことができるようになります。
例を見てみましょう。以下のように読み込み対象のソースコードとして some_source_code.js
を作成します。
export const hello = "Hello Deno!";
このファイルを、以下のようにして動的インポートすることができます。
const sourceCode = await Deno.readTextFile("./some_source_code.js");
const dataUrl = "data:text/javascript;base64," + btoa(sourceCode);
const c = await import(dataUrl);
console.log(c.hello); // "Hello Deno!" が出力される
なお、例のように、一度 Data URI に変換しなければならないということに注意してください。直接ファイルシステム上あるいはネットワーク越しにインポートをすることは、現状では不可能です。
また、もう 1 つ deno compile
への要望として、ランタイムで利用できるコンパイラ API である Deno.emit() を使いたい、というものがありました。今回のバージョンからこの API も deno compile
の生成バイナリ内で利用できるようになりました。
TextEncoderStream
と TextDecoderStream
がサポートされる
6. 2 つのモダンな Web API TextEncoderStream
と TextDecoderStream
が実装されました。ReadableStream
とともに使うことで、簡単にバイト列を文字列に、あるいは文字列をバイト列に変換することができます。
以下の例では、fetch
のレスポンスボディストリームを TextDecoderStream
にパイプしています。これによってバイト列ストリームから文字列セグメントへと変換されます。
const response = await fetch("https://http2.golang.org/clockstream");
const body = response.body.pipeThrough(new TextDecoderStream());
for await (const chunk of body) {
console.log("!!chunk start!!", chunk, "!!chunk end!!");
}
BroadcastChannel
が実験的サポート
7. --unstable
フラグの下で BroadcastChannel
のプロトタイプが利用できます。BroadcastChannel
を使うことで、複雑な JavaScript オブジェクトからなるメッセージを、ワーカー間で配信することができます。現在は同一プロセス内のワーカーに制限されていますが、将来的には、別プロセスのワーカー間でも、オリジン[1]が同じなのであれば配信を行うことができるようになる予定です。
以下の例は、ワーカーを 3 つ立ち上げて、それらにメッセージを送っています。
const c = new BroadcastChannel("foo");
const url = new URL("./worker.js", import.meta.url).href;
for (let i = 0; i < 3; i++) {
const w = new Worker(url, { type: "module" });
await new Promise((resolve) => w.onmessage = resolve); // ワーカーの準備ができるまで待つ
}
c.postMessage({ hello: [1, 2, 3] });
const c = new BroadcastChannel("foo");
self.postMessage("ready");
c.onmessage = (e) => {
console.log("got message", e.data);
};
8. Deno LSP に様々な改良
Deno の内蔵 LSP にも多くの機能追加がされました。1 つずつ紹介します。
個々のテストケースを実行できる
https://deno.com/blog/v1.11 より
Deno.test
で書いたテストケースの上に Run Test
が出現するようになり、これをクリックすることでテストケースを個別実行することができるようになりました。
VSCode でこの機能を利用するためには Deno 拡張 の v3.6.0 以降が必要です。
リソース単位の設定をサポート
Language Server Protocol の一部として、リソース単位の設定ができるようになりました。これは VSCode においては、マルチルートワークスペースで異なるフォルダに対して特定の設定を行うことができる、ということになります。詳しくは ワークスペースフォルダに関するドキュメント を参照してください。
レジストリの自動検出
Deno 1.10 から、import
を書くときの自動補完機能が追加されています。しかし、1.10 では、補完対象とするレジストリを手動で設定に追記しなければなりませんでした。
今回のバージョンからは、import
補完機能に対応しているレジストリから import
しようとしていることを検知すると、以下のようにプロンプトが出現するようになります。これによって、手動で設定ファイルを編集する必要がなくなります。
https://deno.com/blog/v1.11 より
JSON(C) および Markdown のフォーマットをサポート
これまで JavaScript、JSX、TypeScript、TSX のフォーマットには対応していましたが、今回のバージョンから JSON、JSONC、Markdown のフォーマットも行えるようになりました。
https://deno.com/blog/v1.11 より
X-Deno-Warning
の内容を表示
Deno のモジュールを配信するサーバーは、X-Deno-Warning
ヘッダを付けることで、何らかの警告情報をクライアント側に知らせることができます。例えば、deno.land/x
は、以下のようにバージョンを指定しないインポートをしようとしたとき、X-Deno-Warning
ヘッダに警告メッセージをセットします。
import { Application } from "https://deno.land/x/oak/mod.ts";
今回のバージョンから、このヘッダにセットされた警告メッセージを、LSPが表示してくれるようになりました。
https://deno.com/blog/v1.11 より
deno lint
のヒントを表示
deno lint
は、何らかの問題を検出した際、メッセージとともに、どのようにすれば問題を直すことができるのかを示す「ヒント」を提供しています。しかし、Deno LSP はこれまで、この「ヒント」を表示していませんでした。
v1.10 での表示 https://deno.com/blog/v1.11 より
今回のバージョンからは、以下のようにヒントを合わせて表示するようになりました。
v1.11 での表示 https://deno.com/blog/v1.11 より
@deno-types
と triple-slash reference に対応した診断結果を表示
// @deno-types
および /// <reference />
(triple-slash directives) を解釈できるようになり、これらのコメントに対する診断結果を表示するようになりました。
Deno
名前空間のいくつかの API の引数が変更
9. 以下の 9 API の引数に修正が入りました。
Deno.chdir
Deno.realPath
Deno.realPathSync
Deno.rename
Deno.renameSync
Deno.symlink
Deno.symlinkSync
Deno.utime
Deno.utimeSync
これらの API は、引数にファイルパスを表す string
を受け取るのですが、今回の修正で URL
型も受け取れるようになりました。ただし、file://
から始まる URL のみ正しく動作します。
既存の string
型の引数も依然として問題なく動くため、後方互換性は保たれています。
10. TypeScript 4.3
内蔵されている TypeScript のバージョンが 4.3.2 になりました。
11. Web Platform Tests の対応状況を可視化
Deno は Web 標準への準拠を目指していて、ブラウザ上で動く API との互換性を高めるため多くのコントリビュータが貢献しています。
Web API との互換性を高めるための指標として役立つのが、Web Platform Tests (WPT) です。Chrome、Firefox、Safari などのブラウザがこのテストスイートを共有することで、Web API のブラウザ間での互換性が担保されています。
Deno も WPT を実行しており、現在どれくらいのテストが通っているのかを確認できるダッシュボードが公開されました。
主要ブラウザのテスト結果がまとめられている https://wpt.fyi/ に Deno を追加する作業が進行中とのことです。また、どの Web API が Deno で利用可能なのかを MDN にも掲載する作業も進行中のようです。
おわり
以上、1.11.0 の紹介でした。
次のマイナーバージョン 1.12.0 のリリースは 2021 年 7 月 13 日の予定です。
過去のリリース情報
1.10.1
1.9.0
1.8.0
1.7.0
1.6.0
-
オリジンとは、URL のうちプロトコル、ホスト名、ポート番号の部分のことです。Deno においては起動時のオプション
--location
で指定可能です。 ↩︎
Discussion