Deno v1.33がリリースされました。

この記事では主な変更点などについて解説します。

dynamic importに関するパーミッションチェックの見直し

静的に解析可能なdynamic importの実行時に、パーミッションが要求されないように挙動が変更されました。

このリリース以降、以下のコードを実行する際に--allow-netの指定が不要になります。(v1.32までは--allow-netが要求されます)

const { delay } = await import("https://deno.land/std@0.185.0/async/delay.ts");
await delay(3000);

ただし、以下のようにURLを動的に構築している場合などは、従来通り--allow-netの指定が必要です。

// Denoが`import()`の引数を静的に解析できない場合は、従来どおりパーミッションが要求されます
const { delay } = await import(`https://deno.land/std@0.185.0/async/${"delay.ts"}`);
await delay(3000);

Deno KV

Deno.AtomicOperationmin/maxメソッドが追加

minは引数で指定された値と現在の値を比較し、小さい方の値でエントリを上書きします。maxはその逆の操作です。

const kv = await Deno.openKv(":memory:");

const result = await kv.set(["key"], new Deno.KvU64(1n));

const commitResult = await kv.atomic()
  .check({ key: ["key"], versionstamp: result.versionstamp })
  .max(["key"], 2n)
  .commit();
assert(commitResult.ok);

const result2 = await kv.get(["key"]);
assert(result2.value instanceof Deno.KvU64);
assert(result2.value.value === 2n);

Deno.AtomicOperation.commitの戻り値の変更

Deno.AtomicOperation.commitの戻り値の型がPromise<KvCommitResult | null>からPromise<KvCommitResult | KvCommitError>へ変更されています。

また、Deno.KvCommitResultokプロパティが追加されています。

今後、commitの成功可否を判断する際はokを参照する必要があります。

v1.33

const kv = await Deno.openKv(":memory:");

const commitResult = await kv.atomic()
  .set(["key"], 2n)
  .commit();
assert(commitResult.ok); // 成功可否を判断するには`ok`を参照する必要があります
assert(commitResult.versionstamp);

v1.32

const kv = await Deno.openKv(":memory:");

const ok = await kv.atomic()
  .set(["key"], 2n)
  .commit();
assert(ok); // `null`でなければ成功

Deno.serve()

このリリースではDeno.serve()に関する改善などが実施されています。

Deno.serve()は来月に安定化が予定されているようです。 (次のDeno v1.34で安定化される可能性がありそうです)

Flashの削除

Deno.serveのバックエンドとして使用されていたFlashが削除され、hyper v1.0-rc3をベースに改めてリライトされました。

また、これに伴ってHTTP/2の対応も進んでいて、h2cのサポートが入っています。

const ac = new AbortController();
const server = Deno.serve(
  () => new Response("foobar"),
  { signal: ac.signal },
);
$ curl --http2 --http2-prior-knowledge http://localhost:8000
foobar

シグネチャの変更

具体的には、以下のようなDeno.serve(handler, options)形式の呼び出しができなくなります。

const handler = (request) => {
  // ...
  return new Response(body);
};
const ac = new AbortController();
Deno.serve(handler, {
  signal: ac.signal,
});

上記の形式を利用していた場合は、以下のように書き換える必要があります。

const handler = (request) => {
  // ...
  return new Response(body);
};
const ac = new AbortController();
Deno.serve({
  signal: ac.signal,
}, handler);

// または以下でも可
Deno.serve({
  handler,
  signal: ac.signal,
});

Deno.runの非推奨化

Deno.run()が非推奨化されました。

今後はv1.31で安定化されたDeno.Commandの使用が推奨されます。

Deno.run()はv2.0で削除される予定のようです。

Node.js互換性の改善

node:crypto

node:cryptoで以下のAPIが実装されています。

  • getCurves
  • ECDH.generateKeys
  • ECDH.computeSecret
  • ECDH.getPrivateKey
  • ECDH.getPublicKey
  • ECDH.setPrivateKey
  • verify
  • sign
  • generateKeyPair
  • generatePrime (safe/add/remオプションは未実装)

node_modulesに関する改善

pnpmなどと同様に、node_modulesディレクトリの直下にはトップレベルのパッケージのみが含まれるように修正されています。

これにより、node_modulesの初期化の高速化などが見込まれるようです。

CLI

deno.json(c)のフラット化

deno lintdeno fmtなどの実行対象ファイルをより簡易的に指定できるようになりました。

例えば、Deno v1.32ではdeno lintの適用対象を設定するには、以下のように指定する必要がありました。

{
  "lint": {
    "files": {
      "exclude": [
        "fresh.gen.ts"
      ]
    }
  }
}

このリリースでは、以下のように記述することができます。

{
  "lint": {
    "exclude": [
      "fresh.gen.ts"
    ]
  }
}

また、deno fmtの挙動をカスタマイズするための指定も簡略化されています。

例えば、v1.32では以下のように指定する必要がありました。

{
  "fmt": {
    "options": {
      "singleQuote": true
    }
  }
}

Deno v1.33ではoptionsの指定を省略できます。

{
  "fmt": {
    "singleQuote": true
  }
}

これらの変更に合わせて、fmt.optionslint.filesなどのオプションが非推奨化されています。

deno bench --no-run

deno bench--no-runオプションがサポートされました。

deno testの同名オプションと同様に、このオプションを指定した際は、ベンチマークは実行されずに型チェックのみが実行されます。

deno taskunsetコマンドがサポート

指定した変数を削除することができます。

{
  "tasks": {
    "test": "unset DENO_DIR && deno eval 'console.info(Deno.env.has(`DENO_DIR`))'"
  }
}

URL.canParse

URL.canParseが実装されました。

assert(URL.canParse("node:path"));
assert(URL.canParse("https://deno.land/"));
assert(URL.canParse("file:///foo.js"));
assert(!URL.canParse("./foo.js"));

FFI

オプショナルなシンボルのサポート

Deno.dlopenで特定のシンボルをオプショナルとして宣言できるようになりました。

optionalオプションにtrueを指定しておくと、対象のシンボルが存在しない場合に発生するFailed to register symbol 〜エラーを回避できます。

const dylib = Deno.dlopen("somelib.so", {
  no_such_symbol: {
    parameters: [],
    result: "void",
    optional: true,
  }
});

assert(dylib.symbols.no_such_symbol == null);

Deno.test()の改善

ignoreonlyなどのboolean型のオプションにundefinedを指定すると、エラーが発生する問題が修正されています。

これらのオプションにundefinedが指定された際は、デフォルトでfalseが使われます。


その他には、reportErrorDeno.testの実行中に呼ばれるとプロセスがパニックする問題が修正されています。

その他

  • URLPatternComponentResultgroupsの型がRecord<string, string>からRecord<string, string | undefined>へ変更されています。
  • deno coverageでテストファイルが集計対象から除外されるように修正されました。
  • V8がv11.4へアップデートされています。

参考