Deno 1.14.0 がリリースされたので新機能や変更点の紹介
Copyright (c) 2018-2021 the Deno authors. MIT License.
日本時間の昨日(2021 年 9 月 15 日)に Deno の v1.14.0 がリリースされました。
詳細なリリース内容は上記のリリースノートにまとまっていますが、ざっと紹介していきたいと思います。
- Web Crypto API の追加
-
deno lint
とdeno fmt
に対するカスタマイズオプションの追加 -
URLPattern
の実装 - ネイティブ実装されたサーバーサイド WebSocket API の安定化
-
ArrayBuffer
がコピーなしでワーカー間を移動できるように - ファイルをロックする API の追加
- OS シグナル API の変更
-
fetch
で相互 TLS がサポート -
DENO_AUTH_TOKENS
でBASIC認証をサポート - URLのパースが3倍速になった
- 子プロセスの user id および group id を指定することができるように
-
std/http
モジュールが高速化 - VSCode 拡張機能のアップデート
- TypeScript 4.4 にアップデート
- V8 9.4 にアップデート
Web Crypto API の追加
1.最近のリリースでは毎度のように Web Crypto API が拡充されていますが、今回のバージョンでも例にもれず API の追加実装がなされました。
-
crypto.subtle.exportKey()
:- HMAC キーが JWK および raw 形式でエクスポートできるようになった
- RSA キーが PKCS #8 形式でエクスポートできるようになった
-
crypto.subtle.importKey()
:- HMAC キーが JWS および raw 形式でインポートできるようになった
- RSA キーが PKCS #8 形式でインポートできるようになった
- PBKDF2 キーが raw 形式でインポートできるようになった
-
crypto.subtle.generateKey()
:- RSA-OAEP, ECDH, AES キーの生成ができるようになった
-
crypto.subtle.deriveBits()
:- PBKDF2, HKDF の導出ができるようになった
-
crypto.subtle.verify()
:- ECDSA 署名の検証ができるようになった
-
crypto.subtle.encrypt()
:- RSA-OAEP アルゴリズムによる暗号化ができるようになった
-
crypto.subtle.decrypt()
:- RSA-OAEP アルゴリズムによる復号化ができるようになった
まだまだ Web Crypto API の追加作業は引き続き行われています。年内にはすべての API を実装する見込みです。興味のある方は Tracking issue を参照してください。
deno lint
と deno fmt
に対するカスタマイズオプションの追加
2. Deno はリンターとフォーマッタを内蔵していますが、これらはこれまでユーザーによる設定をすることができませんでした。つまり、リンターであれば、例えば特定のリントルールを無効化したり、逆にデフォルトでは無効になっているルールを有効化したり、といったことができませんでした。フォーマッタであれば、1行あたりの文字数や文末セミコロンの有無などを設定することができませんでした。
統一されたリンター・フォーマッタを適用することで、エコシステム全体としての利益になるという考えのもとこのようなデザインとなっていましたが、ユーザーから数多くの要望が寄せられたため、今回のバージョンからこれらのツールをユーザー側で設定できるような仕組みが追加されました。僕の認識では、特に deno fmt
が提供するフォーマットルールに対する意見がかなり多かったように思います。1行の文字数が80と指定されていたのは度々議論を巻き起こしました。
ただし、依然としてこれらのツールはデフォルト設定のまま使うことが望ましいとされています。特段の理由がない限りはデフォルトで使うのが良いと思います。
設定の仕方をかんたんに紹介します。コマンドのオプションとして渡すやり方と、設定ファイルに記載するやり方があります。設定ファイルを使う場合、以下のような JSON ファイルを用意します。
{
"compilerOptions": {
"allowJs": true,
"lib": ["deno.window"],
"strict": true
},
"lint": {
"files": {
"include": ["src/"],
"exclude": ["src/testdata/"]
},
"rules": {
"tags": ["recommended"],
"include": ["ban-untagged-todo"],
"exclude": ["no-unused-vars"]
}
},
"fmt": {
"files": {
"include": ["src/"],
"exclude": ["src/testdata/"]
},
"options": {
"useTabs": true,
"lineWidth": 80,
"indentWidth": 4,
"singleQuote": true,
"proseWrap": "preserve"
}
}
}
最初にある compilerOptions
は、これまで deno run --config
に渡して利用することのできた設定です。リンターおよびフォーマッタは、これまでの設定ファイルを拡張する形で設定を行います。設定の内容については直感的にわかると思うので、詳しくは省略します。files
で対象とするファイル、対象外とするファイルを指定し、rules
では有効にしたいリントルールと除外したいリントルールを指定します。options
では lineWidth
(1行あたりの行数) などを指定できます。
以上が設定ファイルを利用する場合の方法ですが、注意すべき点として、設定ファイルの自動検出機能は未実装であるということです。つまり、この設定ファイルを利用するためには、deno lint --config ./deno.json
のように明示的に設定ファイルの場所を指定する必要があります。将来的に自動検出機能は実装される予定ですが、その際のファイル名は deno.json
あるいは deno.jsonc
となる予定なので、特にこだわりがなければこれらのファイル名にすることをおすすめします。
そして、コマンドラインオプションとして設定値を渡す方法ですが、上記の JSON ファイルのキーの名前がそのままオプション名となります。例えば deno lint
に対しては --rules-include
--rules-exclude
、 deno fmt
に対しては --options-line-width
、 --options-indent-width
のような感じです。
URLPattern
の実装
3. URLPattern
という新しい Web API があります。(W3C のドラフトはこちら) path-to-regex のような API となっています。具体例を見ていただくのがわかりやすいと思います:
const pattern = new URLPattern({ pathname: "/books/:id" });
console.log(pattern.test("https://example.com/books/123")); // true
console.log(pattern.test("https://example.com/books/123/456")); // false
console.log(pattern.test("https://example.com/books")); // false
console.log(pattern.exec("https://example.com/books/123")?.pathname);
// { input: "/books/123", groups: { id: "123" } } が得られる
これが Web API として提供されるのはかなり利便性が高そうですね!
1.14 時点では不安定機能のため、--unstable
フラグが必要です。Chrome 95 にて安定化される予定で、それに合わせて Deno でも安定化される予定です。
4. ネイティブ実装されたサーバーサイド WebSocket API の安定化
1.12 にて ネイティブ HTTP サーバー実装による WebSocket API が導入されました。
この API は不安定機能とされていて、これまでは --unstable
フラグが必要でした。しかし今回のバージョンから安定化され、--unstable
なしで利用できるようになります。
ArrayBuffer
がコピーなしでワーカー間を移動できるように
5. これまで、ArrayBuffer を別ワーカーに移動させたい場合は、コピーをする必要がありました。これはバッファのサイズが大きい場合かなりのオーバーヘッドとなってしまいます。
1.14 からは、コピーするのではなく、所有権を別ワーカーに移動させることができるようになりました。移動させたあと、元のワーカーではそのバッファを使うことができなくなります。
別ワーカーに ArrayBuffer を移動させるためには、postMessage()
関数の transfer
オプションに移動させたいバッファを指定してください。
6. ファイルをロックする API の追加
ファイルに対する同期機構であるファイルロックですが、このファイルロックを行うための 4 つの API が追加されました。
Deno.flock
Deno.flockSync
Deno.funlock
Deno.funlockSync
不安定機能のため、--unstable
フラグが必要です。
7. OS シグナル API の変更
Deno が提供している OS シグナル API に大きな改修が入りました。これまでシグナルの種類は Deno.Signal
という enum で表現されていましたが、1.14 からは string の union として定義されました。つまり、SIGTERM をハンドリングするコードは、以下のように変わります。
// 1.14 よりも前のバージョン
for await (const _ of Deno.signal(Deno.Signal.SIGTERM)) {
console.log("got SIGTERM!");
}
// 1.14 以降のバージョン
for await (const _ of Deno.signal("SIGTERM")) {
console.log("got SIGTERM!");
}
また、いくつかのヘルパーメソッドを提供していた Deno.signals
名前空間が完全に削除されました。
シグナルに関する API の安定化がまもなくなされる予定です。
fetch
で相互 TLS がサポート
8. fetch
API にて、相互TLS (mutual TLS, mTLS とも) がサポートされました。クライアント側の証明書と秘密鍵を指定して Deno.createHttpClient
を呼び出し、それを fetch
に渡すことで利用可能になります。以下のような感じです。
const client = Deno.createHttpClient({
certChain: Deno.readFileSync("./cert.pem"),
privateKey: Deno.readFileSync("./key.pem"),
});
const resp = await fetch("https://example.com/", { client });
DENO_AUTH_TOKENS
でBASIC認証をサポート
9. Deno 1.8 から DENO_AUTH_TOKENS
環境変数が使えるようになりました。 この環境変数に Bearer トークンを指定することで、認証が必要なサーバーからモジュールを取得することができます。
今回のバージョンから、この環境変数を使って、BASIC 認証も突破できるようになります。username:password@host
の形式で指定します。以下のような感じです:
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land;testuser123:testpassabc@127.0.0.1:4554
このように指定すると、
-
deno.land
にはa1b2c3d4e5f6
という Bearer トークンを使ってアクセスする -
127.0.0.1:4554
には ユーザー名:testuser123
パスワード:testpassabc
でアクセスする
というようになります。
10. URLのパースが3倍速になった
数週間前に「うそ、Deno の URL のパース、遅すぎ……?」という旨の報告がありました。これを受けて内部実装が調査・改善され、結果として v1.13 に比べて 3 倍のパフォーマンスとなりました。URL のパースは Web サーバーなどの用途で極めて多く行われる処理なため、この改善によるパフォーマンスへの効果は大きいと考えられています。
11. 子プロセスの user id および group id を指定することができるように
Deno で子プロセスを立ち上げる API として Deno.run()
がありますが、この API で子プロセスの user id および group id を指定することができるようになりました。以下のように使います。
// uid (user id) を指定
Deno.run({
cmd: [
"echo",
"Hello from root user",
],
uid: 0,
});
// gid (group id) を指定
Deno.run({
cmd: [
"echo",
"Hello from root group",
],
gid: 0,
});
この機能は不安定機能のため、実行するには --unstable
フラグが必要です。
std/http
モジュールが高速化
12. Deno v1.13 にて HTTP サーバーのネイティブ実装が安定化 され、パフォーマンスが飛躍的に向上しました。これに伴って標準ライブラリの HTTP モジュール std/http
はじきに削除される予定とされていましたが、Deno の標準ライブラリ v0.107.0 にて、ネイティブ実装 HTTP を利用するように標準ライブラリが改修されました。これで、std/http
を利用する場合でもネイティブ実装による高速なパフォーマンスを得ることができるようになります。また、API も標準ライブラリ版のほうがよりユーザーフレンドリーな形になっています。
(🤔 std/http
の削除はこれでなくなったのかな……)
13. VSCode 拡張機能のアップデート
VSCode 拡張機能 もアップデートされました。デバッグ設定の改善、コードレンズを利用する際の設定の改善、インストールサイズと起動時間の改善、設定ファイルとして deno.json
deno.jsonc
のサポート、など。
14. TypeScript 4.4 にアップデート
Deno に組み込まれている TypeScript のバージョンが 4.4 にあがりました。catch 句でキャッチされた値の型を unknown
にすることができる --useUnknownInCatchVariables
フラグなどが嬉しいアップデートです。TypeScript 4.4 自体の紹介は TypeScript 公式のリリース告知 をご覧ください。
15. V8 9.4 にアップデート
V8 のバージョンが 9.4 に上がりました。ユーザーに関係する一番大きな変更は、ES2022 の新しい言語機能である static initialization block がサポートされたことです。以下のようなコードを書くことができます。
class C {
// このブロックは、class 自体が評価されるタイミングで一度だけ実行される
static {
console.log("Why is it always raining in Deno land?");
}
}
おわり
以上、1.14.0 の紹介でした。
次のマイナーバージョン 1.15.0 のリリースは 2021 年 10 月 12 日の予定です。
なお、Deno 2.0 に向けての議論も始まっています。今のところ、11月に行われる予定(つまり 1.15 の次に 2.0 になる予定)ですが、大きな機能追加があるというよりは、破壊的な変更になってしまうため取り入れることができなかった機能がたまってきたので、その整理のためのメジャーバージョンアップとなる見込みです。詳しくは 2021年9月9日に行われたデザインミーティングの議事録 をご覧ください。
過去のリリース情報
1.13.0
1.12.0
1.11.0
1.10.1
1.9.0
1.8.0
1.7.0
1.6.0
Discussion