Deno v1.30がリリースされました。
この記事では主な変更点などについて解説します。
Node.js互換性の改善
2023年 Q1のロードマップで発表されていたNode.js組み込みパッケージの利用が正式にサポートされました。
以下のように、node:<パッケージ名>
の形式でimport
を記述すると、Node.js組み込みパッケージをDenoから利用することができます。
import { EventEmitter } from "node:events";
const emitter = new EventEmitter();
emitter.on("foo", console.log);
emitter.emit("foo", "bar");
また、Node-APIの互換性の改善も引き続き実施されており、以下のAPIなどの互換性が向上されています。
deno.json
でのImport Mapsの定義がサポート
こちらも2023年 Q1のロードマップで発表されていた機能になります。
deno.json
でimports
やscopes
などが定義されていると、--import-map
使用時と同様に、deno.json
の定義内容を元にDenoがbare specifierが解釈してくれます。
例えば、以下のような内容のdeno.json
が存在したとします。
{
"imports": {
"dax": "https://deno.land/x/dax@0.24.0/mod.ts"
}
}
この場合、ソースコードでは以下のようにしてdax
モジュールを利用することができます。
import { $ } from "dax";
await $`echo foobar`;
deno fmt
でセミコロンの有無を制御できるように
今まで、Denoに搭載されたフォーマッタであるdeno fmt
コマンドでは、ソースコードにおける行末のセミコロンの有無をカスタマイズすることができませんでした。
今回のリリースでは、deno.json
でfmt.options.semiColons
オプションがサポートされました。
このオプションにfalse
を設定すると、deno fmt
の実行時に行末のセミコロンが取り除かれます。
{
"fmt": {
"options": {
"semiColons": false
}
}
}
また、--options-no-semicolons
オプションにより、CLI経由でセミコロンの有無を制御することも可能です。
このオプションを指定した場合も、フォーマット時に行末のセミコロンが取り除かれます。
$ deno fmt --options-no-semicolons main.ts
Deno.permissions
に同期バージョンのAPIが追加
DenoはDeno.permissions
名前空間でquery()
やrequest()
などのパーミッションを動的に制御するためのAPIを提供しています。
これらのAPIはすべて非同期に動作し、戻り値としてPromise
を返却します。
このリリースでは、パーミッションを同期的に制御したいケースに対応するため、Deno.permissions
名前空間に以下の3つのメソッドが新しく追加されました。
querySync()
requestSync()
revokeSync()
挙動としては、各メソッドの非同期バージョン(名前にSync
がつかないメソッド)と同様ですが、戻り値としてPromise
ではなく直接結果が返却されます。
const status = Deno.permissions.querySync({ name: "env", variable: "DENO_DIR" });
if (status.state === "granted") {
const denoDir = Deno.env.get("DENO_DIR");
console.info(denoDir);
}
Deno.env.has
の追加
新しいAPIとしてDeno.env.has
が実装されました。
引数で指定した環境変数が定義されていれば、true
が返却されます
console.log(Deno.env.has("DENO_DIR"));
このAPIの利用には--allow-env
の指定が必要です。
Deno.test
のサブステップAPIでテスト関数を直接渡せるように
Deno.test
では以下のように関数を直接渡してテストケースを定義することができます。
Deno.test(function sumReturnsSumOfNumbers() {
assertEquals(sum(1, 2, 3), 6);
});
しかし、サブステップAPI(Deno.TestContext#step
)にはこのようにして関数を渡すことができませんでした。
このリリースでは、サブステップAPIでも関数を直接渡すことができるように改善されています。
以下のように、step()
の引数として直接テスト関数を渡すことができます。
Deno.test("sum", async (t) => {
await t.step(function shouldReturnSumOfNumbers() {
assertEquals(sum(1, 2, 5), 8);
});
});
Deno.Command#spawn
でstdin
オプションのデフォルト値が"inherit"
に変更
Deno.Command
の生成時にstdin
オプションが未指定の状態でspawn
を実行した際は、 stdin
オプションに"inherit"
が指定された場合と同様の振る舞いをするように挙動が変更されています。
もし今までのバージョンと同じ振る舞いが必要な際は、stdin
オプションに"null"
を明示する必要があります。
const command = new Deno.Command(cmd, {
args,
stdin: "null",
});
Deno.writeFile()
とDeno.writeTextFile()
でReadableStream
がサポート
Denoからファイルへ書き込みを行うためのAPIであるDeno.writeFile()
とDeno.writeTextFile()
にReadableStream
を渡せるようになりました。
const stream = new ReadableStream({
pull(controller) {
controller.enqueue("foo\n");
controller.enqueue("bar");
controller.close();
},
});
await Deno.writeTextFile("test.txt", stream);
console.info(await Deno.readTextFile("test.txt"));
// Output: foo
// bar
Deno.FsFile#seek
のoffset
引数でbigint
がサポート
以下のように、Deno.FsFile
のseek()
メソッドにbigint
を渡せるようになりました。
const file = await Deno.open(filename);
try {
await file.seek(3n, Deno.SeekMode.Start);
const buf = new Uint8Array(100);
await file.read(buf);
console.info(new TextDecoder().decode(buf));
} finally {
file.close();
}
Deno.Listener
のref()
とunref()
メソッドが安定化
Deno.listenr
のref()
/unref()
が安定化され、--unstable
オプションなしで利用できるようになりました。
Deno.Listener
はDeno.listen()
などのAPIから返却されるオブジェクトです。
デフォルトでは、生存中のDeno.Listener
が存在する場合、Denoのプロセスの終了はブロックされます。
Deno.Listener
のunref()
メソッドを呼ぶと、該当のリスナがプロセスの終了をブロックしなくなります。
ref()
メソッドはその逆で、unref()
されたDeno.Listener
をデフォルトの状態へ戻します。(プロセスの終了がブロックされるようになります)
DENO_V8_FLAGS
環境変数のサポート
今まで、Denoの内部で実行されるv8の挙動をカスタマイズしたい場合は、Denoの実行時に--v8-flags
オプションを指定する必要がありました。
このリリースでは、DENO_V8_FLAGS
環境変数がサポートされています。
今後は、この環境変数経由でもv8の挙動をカスタマイズできます。
deno upgrade
の改善
deno upgrade
の実行後に、アップデート後のバージョンのリリースノートへのリンクが表示されるようになりました。