Deno v2.1がリリースされました。

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

.wasmファイルのimportがサポート

.wasmファイルのimportがサポートされました。

通常のJavaScriptモジュールと同様に、リモートの.wasmファイルをimportすることもできます:

import { add } from "https://raw.githubusercontent.com/denoland/deno/refs/tags/v2.1.0/tests/testdata/wasm/math.wasm";

console.info(add(1, 2));

また、deno docコマンドでも.wasmファイルがサポートされています:

$ deno doc https://raw.githubusercontent.com/dyedgreen/deno-sqlite/refs/tags/v3.9.1/build/sqlite.wasm
Defined in https://raw.githubusercontent.com/dyedgreen/deno-sqlite/refs/tags/v3.9.1/build/sqlite.wasm:45:1

function argument_blob(arg0: number): number

  ...

function total_changes(): number

Defined in https://raw.githubusercontent.com/dyedgreen/deno-sqlite/refs/tags/v3.9.1/build/sqlite.wasm:2:22

const memory: WebAssembly.Memory

deno outdated

deno outdatedという新しいコマンドが実装されています。

引数なしで実行すると、各依存関係の最新バージョンが表示されます:

$ deno outdated
┌────────────────────┬─────────┬────────┬────────┐
│ Package            │ Current │ Update │ Latest │
├────────────────────┼─────────┼────────┼────────┤
│ jsr:@oak/oak       │ 17.1.0  │ 17.1.3 │ 17.1.3 │
├────────────────────┼─────────┼────────┼────────┤
│ jsr:@hono/hono     │ 4.6.4   │ 4.6.11 │ 4.6.11 │
├────────────────────┼─────────┼────────┼────────┤
│ npm:@nestjs/common │ 10.4.4  │ 10.4.8 │ 10.4.8 │
├────────────────────┼─────────┼────────┼────────┤
│ npm:@nestjs/core   │ 10.4.4  │ 10.4.8 │ 10.4.8 │
└────────────────────┴─────────┴────────┴────────┘

引数を指定することで、指定したパターンにマッチするパッケージの情報のみを表示できます:

$ deno outdated "@nestjs/*"
┌────────────────────┬─────────┬────────┬────────┐
│ Package            │ Current │ Update │ Latest │
├────────────────────┼─────────┼────────┼────────┤
│ npm:@nestjs/common │ 10.4.4  │ 10.4.8 │ 10.4.8 │
├────────────────────┼─────────┼────────┼────────┤
│ npm:@nestjs/core   │ 10.4.4  │ 10.4.8 │ 10.4.8 │
└────────────────────┴─────────┴────────┴────────┘

--compatibleを指定すると、deno.jsonで宣言されたバージョンレンジに基づいて、アップデート可能なパッケージのみが表示されます:

$ deno outdated --compatible

--updateオプションを指定することで、依存関係をアップデートできます:

# deno.jsonで指定されたバージョンレンジに基づいて指定されたパッケージを更新する
$ deno outdated --update "@nestjs/*"

# バージョンを明示する
$ deno outdated --update @nestjs/common@^10.4.8 @nestjs/core@^10.4.8

--latestオプションを指定すると、deno.jsonで指定されたバージョンレンジに関わらず、常に最新バージョンへアップデートしてくれるようです:

$ deno outdated --update --latest "@nestjs/*"

また、ワークスペースの各メンバーの依存もアップデートしたい場合、--recursiveオプションを指定します:

$ deno outdated --recursive --update

deno task

タスク間の依存関係の定義がサポート

各タスク間の依存関係の定義がサポートされています。

この機能の導入に伴い、オブジェクト形式でのタスクの定義がサポートされています。現状ではcommand, description, dependenciesの3つのプロパティーを指定できます。

タスク間の依存関係を定義したい場合、dependenciesプロパティーを指定する必要があります:

{
  "tasks": {
    "check:all": {
      "command": "echo 'All checks have been passed!'",
      "description": "Run all checks",
      "dependencies": ["check:fmt", "check:deno-json"]
    },
    "check:fmt": "deno fmt --check",
    "check:deno-json": {
      "description": "Check if deno.json is valid",
      "command": "deno run --allow-read=deno.json tools/check_deno_json.js"
    }
  }
}

上記の場合にdeno task check:allを実行すると、まずcheck:fmtcheck:deno-jsonタスクが並列で実行され、それらが成功した場合のみcheck:allcommandが実行されます。

引数なしでdeno taskを実行すると、descriptionプロパティーに記載された内容がコメントとして表示されます (これに伴い、引数なしのdeno taskコマンドがdeno.jsoncにおいて各タスクに記述されたコメントを認識してくれる機能が削除されています)

 $ deno task
Available tasks:
- check:all
    // Run all checks
    echo OK
    depends on: check:fmt, check:deno-json
- check:fmt
    deno fmt --check
- check:deno-json
    // Check if deno.json is valid
    deno run --allow-read=deno.json tools/check
_deno_json.js

Deno workspacesのサポート

deno taskコマンドに--filterオプションが追加されています。このオプションが指定されると、ワークスペース内において、名前がこのオプションで指定されたパターンにマッチするパッケージで定義されたタスクを実行できるようです:

# 名前が`platform-*`パターンにマッチするメンバーのhiタスクを実行
$ deno task --filter 'platform-*' hi

# すべてのメンバーのhiタスクを実行
$ deno task --filter '*' hi

--evalオプションが追加

指定された引数をDenoに組み込まれたdeno_task_shellを使って評価してくれます:

$ deno task --eval 'cat deno.json | jq .imports'
Task  cat deno.json | jq .imports
{
  "@nestjs/common": "npm:@nestjs/common@^10",
  "@nestjs/core": "npm:@nestjs/core@^10",
  "@oak/oak": "jsr:@oak/oak@^17",
  "@hono/hono": "jsr:@hono/hono@^4"
}

deno init

--npmオプションのサポート

deno init --npm <package名>のように実行すると、npmレジストリからnpm:create-<package名>がダウンロードされ、実行されます。

例えば、以下のコマンドを実行するとcreate-honoパッケージが実行されます:

$ deno init --npm hono
⚠️ Do you fully trust npm:create-hono package? Deno will invoke code from it with all permissions. Do you want to continue? [y/n]
> 

deno compile

実行可能ファイルへのローカルのファイル/ディレクトリの埋め込みがサポート (--include)

ローカルに存在する任意のファイルやディレクトリの実行可能ファイルへの埋め込みがサポートされています:

// main.js
console.info(await Deno.readTextFile(import.meta.dirname + "/data/test.txt"));

deno compile--includeオプションを指定することで、ファイルまたはディレクトリを埋め込むことができます:

$ cat data/test.txt
foo
bar

$ deno compile --output sample --include ./data ./main.js

$ ./sample
foo
bar

V8コードキャッシュのサポート

deno compileで生成される実行可能ファイルにおいてもV8コードキャッシュがサポートされました (この機能はデフォルトで有効化されており、--no-code-cacheで無効化できます)

生成された実行可能ファイルの初回実行時に/tmpにV8コードキャッシュが保存されます。2回目以降の実行時に/tmpに保存されたV8コードキャッシュが読み込まれます。

V8コードキャッシュの保存先について

以下のPRにおいて、V8コードキャッシュの保存先のパスを表示してくれる変更が導入されています:

今後、この変更が導入されれば、以下のようにしてV8コードキャッシュの保存先を確認できるようになりそうです:

$ DENO_LOG=debug ./sample

deno fmt

SQLのフォーマットがサポート

Deno v1.46で導入されたdeno fmtでのYAMLやCSSなどのサポートに続いて、Deno v2.1では.sqlファイルのフォーマットが実験的にサポートされています。

deno.json"unstable": ["fmt-sql"]を指定する または deno fmt--unstable-sqlを指定することで、.sqlファイルのフォーマットが有効化されます。

.gitignoreのサポート

deno fmtコマンドが.gitignoreの内容を参照して、フォーマット対象から除外すべきファイルを判断するよう改善されています。

deno lint

.gitignoreのサポート

deno fmtコマンドと同様に、deno lintコマンドでも.gitignoreの内容を元にチェック対象から除外すべきファイルを判断するよう改善されています。

deno lint --json - checked_filesフィールドの追加

エラーが発生したファイルの一覧が格納されるようです:

$ deno lint --json | jq .checked_files 
[
  "/home/uki00a/ghq/github.com/uki00a/deno-sandbox/main.js"
]

deno lsp

Auto importsでの// @deno-typesディレクティブのサポート

自前で型定義を提供しないnpmパッケージなどに対して、// @deno-types付きでimport文を挿入できるようにする機能が実装されています。

deno.jsonが存在する場合、エディタ向けに定義されたフォーマットに関する設定が無視されるように

インデントなどに関する設定が.vscode/settings.jsonなどの設定ファイルで定義されていると、deno.jsonで定義されたインデントなどの設定が無視されてしまう問題が修正されています。

deno publish

--set-versionオプションの追加

このオプションが指定された場合、パッケージがdeno.jsonで指定されたバージョンではなくこのオプションで指定されたバージョンとして公開されます。

deno info

Web Cache APIのキャッシュ先の表示がサポート

deno infoコマンドがWeb Cache APIのキャッシュ先として利用されるディレクトリを表示してくれるよう改善されています。

deno test

ドキュメント内のコードブロックの実行(--doc)時にコメントが保持されない問題の修正

deno test --docでMarkdownやJSDocコメント内のコードブロックを実行する際に、コメントが削除されてしまい、// @ts-expect-errorなどが動作しない問題が修正されています。

CLI

DENO_TRACE_PERMISSIONS環境変数の導入

DENO_TRACE_PERMISSIONSという環境変数が導入されています。この環境変数を設定すると、パーミッションプロンプトにおいてスタックトレースの表示が有効化され、あるパーミッションがどこで要求されたか判断しやすくなります:

$ DENO_TRACE_PERMISSIONS=1 deno run main.js
┏ ⚠️  Deno requests read access to "/home/uki00a/ghq/github.com/uki00a/deno-sandbox/data/test.txt".
┠─ Requested by `Deno.readFile()` API.
┃  ├─ op_fs_read_file_text_async (ext:core/00_infra.js:260:33)
┃  ├─ Object.readTextFile (ext:deno_fs/30_fs.js:779:24)
┃  └─ file:///home/uki00a/ghq/github.com/uki00a/deno-sandbox/main.js:1:25
┠─ Learn more at: https://docs.deno.com/go/--allow-read
┠─ Run again with --allow-read to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) > 

スタックトレースの収集は高価な処理のため、この機能は本番環境などにおいては無効化することがDenoの公式ブログでは推奨されています。

--env-fileで複数の.envファイルの読み込みがサポート

--env-fileオプションを複数回指定することで、複数の.envファイルの読み込みがサポートされています。

--allow-env - 特定の名前で始まる環境変数の参照がサポート

--allow-envに末尾が*で終わるパターンを指定した際に、該当のパターンに前方一致する環境変数への参照をまとめて許可することができます:

# 名前が`APP_`から始まる環境変数の参照を許可します
$ deno run --allow-env='APP_*' main.js

deno.lock

compilerOptionsで指定された依存関係のサポート

deno.lockdeno.jsoncompilerOptions.jsxImportSourcecompilerOptions.jsxImportSourceTypesなどで指定されたパッケージも追跡してくれるよう改善されています。

Deno API

Deno.telemetry (OpenTelemetryのサポート)

Deno.telemetryという実験的APIが追加されています。--unstable-otelまたはdeno.json"unstable": ["otel"]を指定することで有効化できます。

このDeno.telemetryopentelemetry-jsを連携させるための@deno/otelというJSRパッケージが公開されています。

Deno.jupyter.image

Deno.jupyter.imageというAPIが追加されています。.jpgまたは.pngファイルをパスもしくはUint8Arrayで指定することで、Jupyter Notebook上に指定された画像を表示できるようです。

Deno.FileInfo.ctime

Deno.statなどで返却されるDeno.FileInfoctimeが追加されています。

Deno.serve

ブラウザーからAccept-Encoding: gzip, deflate, br, zstdが指定された場合、Brotliが使用されるよう挙動が改善されています。

Node.js互換性の改善

--unstable-detect-cjsの安定化

--unstable-detect-cjsが指定されたときのみ有効化されていた、package.json"type": "commonjs"が定義されているパッケージで.jsファイルをCommon JSモジュールとして読み込めるようにする機能がデフォルトで有効化されました。

--unstable-node-globalsオプションが追加

このオプションを指定することで、Node.jsの各種グローバルAPIを有効化することができます。例えば、以下のようにNode.jsのグローバルAPIに依存したスクリプトがあったとします:

console.info(setImmediate);

この場合、--unstable-node-globalsオプションを指定することで、DenoでもNode.jsのグローバルAPIが参照されたスクリプトを実行することができます:

# `--unstable-node-globals`なしだとエラーが発生します
$ deno run main.js
error: Uncaught (in promise) ReferenceError: setImmediate is not defined
console.info(setImmediate);
             ^
    at file:///home/uki00a/ghq/github.com/uki00a/deno-sandbox/main.js:1:14

    info: setImmediate is not available in the global scope in Deno.
    hint: Import it explicitly with import { setImmediate } from "node:timers";,
          or run again with --unstable-node-globals flag to add this global.

# `--unstable-node-globals`を指定すると、実行に成功します
$ deno run --unstable-node-globals main.js
[Function: setImmediate]

node:perf_hooks

monitorEventLoopDelay()が実装されました。

node:timers/promises

setInterval()が再実装され、互換性が改善されています。

node:net

createConnection()autoSelectFamilyオプションがサポートされています。

node:module

getBuiltinModule()が実装されています。

node:zlib

crc32()が実装されています。

node:crypto

generateKeyPair()promisify() (node:util)が動作するよう改善されています。

.//<filename>の取り扱いの変更

Node.jsと同様に、.//<filename>という形式のパスを./<filename>として取り扱うよう挙動が修正されています。

deno install

pnpmに合わせて、ライフサイクルスクリプトが実行されたnpmパッケージに対して、再度binエントリがセットアップされるよう挙動が修正されています。Supabase CLIなどが動作しない問題への対策のようです。


Web API

fetch()のリクエストボディでのAsyncIterable<Uint8Array>のサポート

fetch()のリクエストボディに対するAsyncIterable<Uint8Array>のサポートが再導入されています (この機能はDeno v1.46.0で一度導入され、Deno v1.46.2にてrevertされていました)

import { createReadStream } from "node:fs";

const stream = createReadStream("./data.txt");
const res = await fetch("http://localhost:8000/upload", {
  method: "POST",
  body: stream
});

パフォーマンス改善

Windowsでの起動の高速化

いくつかのDLLファイルを遅延読み込みさせることで、Windowsにおける起動速度が改善されているようです。


Out of Memoryエラーへの対策

Out of Memoryエラーへの対策として、V8のデフォルトのヒープ長がシステムで利用可能なメモリに応じて調整されるよう改善されています。

V8 13.0

Denoに組み込まれたV8のバージョンが13.0へアップデートされています。

参考