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

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

npmパッケージのサポート

Denoでnpmパッケージのimportや実行が実験的にサポートされました。

npm installnode_modulesなどを必要とせずにnpmパッケージを利用することができます。

import express from "npm:express@4.18.1";

const app = express();
app.get("/", (req, res) => {
  res.send("Hello");
});

app.listen(3000);

このファイルを実行すると、npmパッケージがダウンロードされた後、ExpressによってHTTPサーバが起動します。

$ deno run --unstable --allow-env --allow-read --allow-net main.mjs

$ curl http://localhost:3000
Hello

他のサードパーティモジュールなどと同様に、初回実行時のみnpmパッケージがダウンロードされ、DENO_DIRにキャッシュされます。(DENO_DIR/npm/registry.npmjs.orgに保存されるようです)

また、npxライクにコマンドを実行することもできます。

$ deno run --unstable --allow-env --allow-read --allow-write npm:make-dir-cli@3.0.0 src/components

制限

  • 現時点では利用するには--unstableが必要になります。
  • また、--allow-env--allow-readも必要になります。
  • ロックファイル/型チェック/deno vendor/deno lsp/deno installなどでは、この機能はまだサポートされていません。

新しいHTTPサーバ (Flash)

DenoにはHyperをベースにしたHTTPサーバ(Deno.serveHttp)が組み込まれています。

このHTTPサーバのさらなる高速化などを目的に、Flashという新しいHTTPサーバが実装されました。

Deno.serveというAPIによって、Flashを起動することができます。

const ac = new AbortController();

Deno.serve((req) => new Response("Hello, Flash"), {
  port: 4500,
  onListen: ({ port, hostname }) => {
    console.log(`Started at http://${hostname}:${port}`);
  },
  onError: (error) => {
    return new Response("Internal Server Error", { status: 500 });
  },
  signal: ac.signal,
});

既存のDeno.serveHttpよりも高レベルなインターフェースを提供しており、std/http/serverライクにHTTPサーバを立てることができます。

その他には、Deno.upgradeHttpRawというDeno.serveHttpにおけるDeno.upgradeHttp相当のAPIも追加されています (将来的には、FlashでもDeno.upgradeHttpがサポートされる予定のようです)

ベンチマークによると、このFlashは既存のHTTPサーバより3倍程高速に動作するという結果も出ているようです。

制限

Flashを利用するには--unstableが必要です。

また、FlashはHTTP/1.1のみをサポートしており、HTTP/2については将来的にサポート予定のようです。

また、Deno.serveHttpと比べると、機能はまだ充実しておらず、将来的に順次サポートが追加されていく予定のようです。(レスポンスの自動圧縮など)

deno initコマンド

npm inityarn initライクにプロジェクトを初期化するためのコマンドが追加されました。

$ deno init my-first-project
✅ Project initialized
Run these commands to get started
  cd my-first-project
  deno run main.ts
  deno test

現状では、main.tsmain_test.tsの2ファイルの生成のみがサポートされています。

以下のPRによると、将来的にはdeno.json(c)やImport mapsファイルの生成なども検討される可能性がありそうです。

feat: add “deno init” subcommand (#15469)

FFIで"buffer"型がサポート (破壊的変更)

Deno.dlopen"buffer"型がサポートされました。

今までは、FFIを介してTypedArrayを渡したい際は"pointer"型を指定する必要がありましたが、今後はこの"buffer"型を使う必要があります。

const dylib = Deno.dlopen(libPath, {
  "do_something_with_buffer": { parameters: ["buffer", "usize"], result: "void" },
});

const data = new Uint8Array([1, 2, 3, 4]);
dylib.do_something_with_buffer(data, data.length);

この"buffer"型に対してもV8 Fast API Callsによる最適化が適用されます。

パフォーマンス最適化

このリリースでは様々なパフォーマンスチューニングが実施されています。

  • swcによる依存関係の解析結果をキャッシュすることで、起動時間の高速化が図られています。
    • Denoは起動時にswcを使用して依存関係の解析を行っているため、その結果をキャッシュすることで効率化が図られています。
    • 解析結果はSQLiteにキャッシュされます。 (DENO_DIR/dep_analysis_cache_v1)
    • またこの変更の影響によりメモリ使用量も大きく削減されているようです。
  • V8 Fast API Callsを使用したopsの最適化の仕組みが導入
  • Deno.open(Sync)やWeb Streams APIなどが最適化
    • 特にファイルの開閉は2.5倍近く高速化されているようです (denoland/deno#15496)

その他の変更点

  • SubtleCrypto.deriveBitsでP-384曲線を使ったECDHアルゴリズムがサポート
  • deno replで関数がハイライトされるようになりました
  • queueMicrotask内で発生したエラーが"error"イベントで捕捉できるように
  • reportErrorのあとに続くコードがない場合に、プロセスがパニックする問題が修正

など

参考