はじめに

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

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

グローバルAPIに関する破壊的変更

タイマーAPI

globalThis.setTimeout()globalThis.setInterval()などのタイマーAPIにおいて、Web標準ではなくNode.jsベースの実装が使用されるように変更されています (#33249)

これにより、これらのAPIからはnumber型ではなくnode:timersモジュールのTimeoutImmediateなどのオブジェクトが返却されます。

また、この変更に伴い、TypeScriptで自動的にlib: ["node"]が設定されるように変更されています (#33823)

URLSearchParams

globalThis.URLSearchParamsがNode.js互換となるように修正されています (#34119)

軽微ですが、コンストラクター引数としてnullundefinedを渡した際の振る舞いが若干異なるようです。

deno add/deno install

npm:プレフィックスの指定の省略がサポート

deno addの引数に指定したパッケージでnpm:及びjsr:が省略された場合、デフォルトでnpm:が指定されたものとみなすよう挙動が変更されています (#33246, #34290)

# 下記は`deno add npm:zod`と同様に振る舞います
$ deno add zod

--prod/--skip-types

deno installコマンドに--prod/--skip-typesオプションが追加されています (#33248)

--prodオプションを指定すると、package.jsondevDependenciesに指定されたパッケージのインストールがスキップされます。

--skip-typesオプションは--prodとの併用が想定されており、指定されるとpackage.json及びdeno.jsonで指定された@types/*パッケージのインストールがスキップされます。

--package-json

deno add/deno install/deno remove/deno uninstallコマンドに--package-jsonオプションが追加されています (#33199)

package.jsondeno.jsonが併用されたプロジェクトにおいてこれらのコマンドを実行するとデフォルトではdeno.jsonが更新されます。--package-jsonオプションを指定することで、更新対象のファイルをdeno.jsonからpackage.jsonに変更できます。

--os/--arch

--os及び--archオプションが追加されています (#32785)

Denoはデフォルトで現在のプラットフォームに基づいてnpmパッケージのoptionalDependenciesにおける適切なプラットフォーム向けの依存関係のみをダウンロードしますが、--os及び--archを使用することでこの挙動を変更し、指定されたOS/アーキテクチャー向けの依存関係のダウンロードを行わせることが可能です。

--archと既存のDENO_INSTALL_ARCH環境変数を併用した場合、--archが優先されます。

deno test

OpsサニタイザーとResourcesサニタイザーがデフォルトで無効化

OpsサニタイザーとResourcesサニタイザーをデフォルトで無効化する変更が実施されています (#33250)

これらを有効化するために、下記いずれかの手段が提供されています。

1. Deno.test

Deno.test()の下記オプションをtrueに設定することで、該当テストケースでサニタイザーを有効化できます:

  • sanitizeOps
  • sanitizeResources

また、テストファイル内でDeno.test.sanitizer()を実行することで、該当のテストファイル内のすべてのテストケースでサニタイザーを有効化できます。

Deno.test.sanitizer({
  ops: true,
  resources: true,
});

Deno.test("doSomething", () => {
  doSomething();
});

2. deno.json

deno.jsonの下記オプションにtrueを設定することで、全テストケースでサニタイザーを有効化可能です:

  • test.sanitizeOps: true
  • test.sanitizeResources: true
{
  "test": {
    "sanitizeOps": true,
    "sanitizeResources": true
  }
}

3. コマンドライン引数

deno testの引数として下記オプションを指定することで、全テストケースでサニタイザーを有効化できます:

  • --sanitize-ops
  • --sanitize-resources

4. 環境変数

下記環境変数に1を設定しておくことで、全テストケースでサニタイザーを有効化できます:

  • DENO_TEST_SANITIZE_OPS
  • DENO_TEST_SANITIZE_RESOURCES

補足

影響の大きい変更であるため、現在、本変更をv3まで延期する提案が行われています (#34322)

Deno.test()timeoutオプションが追加

Deno.test()timeoutオプションが追加されています (#33815)

Deno.test({
  name: "doSomethingAsync",
  // 3秒以内に完了しなければ、テストケースが失敗します
  timeout: 3000,
  async fn() {
    await doSomethingAsync();
  },
});

deno lint

no-node-globals/no-process-globalルールがデフォルトで無効化

前述のタイマーAPIに関する破壊的変更に合わせて、no-node-globals/no-process-globalルールがデフォルトで無効化されています (denoland/deno_lint#1483)

ルールそのものは残っているため、必要に応じて個別に有効化することも可能です。

deno check

deno check --watch

deno checkコマンドで--watchオプションがサポートされています (#34224)

コード変更が検出された際に、Denoが自動で型チェックを再実行してくれます。

deno compile

フレームワークの検出機能

deno compileコマンドにフレームワークの検出機能が追加されています (#33164)

deno compileの引数としてディレクトリが指定された場合、指定されたディレクトリ内に存在する設定ファイル (例: next.config.js)などに基づいて自動的にプロジェクトで使用されているフレームワークが検出され、必要に応じて該当フレームワーク向けのビルドコマンドを実行した上で、最終的に実行可能ファイルを作成してくれます。

現状、以下のフレームワークがサポートされているようです:

  1. Next.js
  2. Fresh
  3. Astro
  4. Nuxt
  5. SvelteKit
  6. Remix
  7. SolidStart
  8. TanStack Start
  9. Vite (SSR)

deno x

--package

deno xコマンドに--packageオプションが追加されています (#32855)

npxにおける同名オプションと同様に、パッケージ名と実行可能ファイルの名前が異なるケースにおいての使用が想定されています (例: typescript)

deno audit fix (deno audit --fix)

deno auditコマンドにfixサブコマンドが実装されています (#32909, #34273)

npm audit fixと同様に、脆弱性が検出されたパッケージのうち、自動でアップデート可能なパッケージに対してアップデートを実施してくれます。

メジャーアップデートが必要なパッケージなどはアップデートがスキップされます。

deno bump-version

deno bump-versionコマンドが実装されています (#30562)

引数の内容に基づいてdeno.jsonversionを更新してくれます。引数にはpatchminor, majorなどの値を指定可能です:

# パッチバージョンを更新
$ deno bump-version patch

# マイナーバージョンを更新
$ deno bump-version minor

また、ワークスペースのサポートも行われています (#33689)。各メンバーのバージョンの一括更新が可能です。まだ引数が省略された場合、Conventional Commitsに基づいてアップデートが必要なパッケージなどを自動で判断してくれるようです。--dry-runオプションによるドライランや--baseオプションによるベースブランチの指定などもサポートされます。

deno why

deno whyコマンドが実装されています (#32908, #34227)

pnpm whyなどと同様に、指定されたパッケージがどこから依存されているのかを調べることができます:

$ deno why @std/internal

deno ci

deno ciコマンドが実装されています (#34235)

node_modulesを削除しつつ--frozen-lockfileと同様の挙動でパッケージのインストールを実施してくれます。

前述の--prod/--skip-typesオプションもサポートされています。

deno transpile

deno transpileコマンドが実装されています (#32691)

指定されたTypeScriptファイルをJavaScriptへトランスパイルしてくれます:

$ deno transpile src/*.ts --outdir dist 
⚠️  deno transpile is experimental and subject to changes
Emit /path/to/deno-json-lint/dist/src/cli.js
Emit /path/to/deno-json-lint/dist/src/config.js
Emit /path/to/deno-json-lint/dist/src/lint.js
Emit /path/to/deno-json-lint/dist/src/permissions.js
Emit /path/to/deno-json-lint/dist/src/rules.js

--declarationオプションを指定することで、型定義ファイル (d.ts) の生成なども可能です。

deno pack

deno packコマンドが実装されています (#32139)

deno packを実行すると、各種TypeScriptソースのトランスパイルや@deno/shim-denoパッケージの注入などを実施した上でnpmレジストリ向けのtarballを生成してくれます:

$ deno pack
Packing @uki00a/deno-json-lint
Check src/cli.ts
  6 modules collected
Could not generate types for 'file:///path/to/deno-json-lint/generated/config-file.v1.ts'. Types will not be included for this module.
import.meta.main is used in src/cli.ts but will always be undefined on Node.js
Could not generate types for 'file:///path/to/deno-json-lint/src/config.ts'. Types will not be included for this module.
Could not generate types for 'file:///path/to/deno-json-lint/src/lint.ts'. Types will not be included for this module.
Could not generate types for 'file:///path/to/deno-json-lint/src/permissions.ts'. Types will not be included for this module.
Could not generate types for 'file:///path/to/deno-json-lint/src/rules.ts'. Types will not be included for this module.
✓ uki00a-deno-json-lint-0.5.0.tgz (31.7KB)


$ tar xvf uki00a-deno-json-lint-0.5.0.tgz


$ tree package 
package
├── LICENSE
├── README.md
├── generated
│   └── config-file.v1.js
├── package.json
└── src
    ├── cli.d.ts
    ├── cli.js
    ├── config.js
    ├── lint.js
    ├── permissions.js
    └── rules.js

2 directories, 10 files

--dry-runオプションによるドライランの実行や--no-deno-shimオプションによる@deno/shim-denoパッケージの注入の無効化などもサポートされています。シンプルなユースケースであれば、dntを代替することもできそうです。

ただし、現時点でDenoでサポートされているのはtarballの作成のみで、npmレジストリへの公開はまだサポートされていません。

deno task

dependenciesによる並列実行時の出力が改善

dependenciesによって並列にタスクを実行する際に、どのタスクからの出力であるかを判別できるよう、それぞれのタスクのログ出力にタスク名がプレフィックスとして付与されるように改善されています (#33805)

$ deno task check
  ...
[check:deno.json] OK
     [check:lint] Checked 86 files
     [check:lint] Checked 102 files

この挙動は--no-prefixオプションによって無効化することも可能です。

catalog:プロトコル

カタログ機能がサポートされています (#32947, #33799, #33816)

ワークスペースのルートにおけるdeno.jsonまたはpackage.jsonにおいてcatalogもしくはcatalogsプロパティーを定義しておくことで、pnpmなどと同様にワークスペースメンバーの各package.jsonにおいてカタログで定義されたパッケージのバージョンをcatalog:形式で参照することができます。

import defer

import deferが実装されています (#32360)

import defer * as configs from "./config.ts";

// `configs`のプロパティーを参照するまで、モジュールの評価が遅延されます
await configs.load();

Web API

OffscreenCanvas

OffscreenCanvasが実装されています (#29357)

この対応に合わせてDeno.UnsafeWindowSurfacegetContext()メソッドにおける"bitmaprenderer"のサポートやheight/widthプロパティーの追加なども行われています。

Geometry Interfaces Module Level 1

Geometry Interfaces Module Level 1が実装されています (#27527)

これによりDOMMatrixDOMPointなどのAPIがサポートされます。

Deno に DOMMatrix を入れるために Rust で CSS Values and Units の構文解析、計算をした話の記事にて詳細な解説が行われています。

Web Crypto APIにおけるSHA3のサポート

SubtleCrypto#digest()で下記アルゴリズムがサポートされています (#32342)

  • SHA3-256
  • SHA3-384
  • SHA3-512

WICG/webcrypto-modern-algosにて提案されている機能のようです。

structuredClone()

Blob及びFileに対するstructuredClone()のサポートが追加されています (#33827, #34075)

OpenTelemetry

OTEL_EXPORTER_OTLP_PROTOCOL=grpc

gRPCによるシグナルのバックエンドへの送信がサポートされています (#30365)

OTEL_EXPORTER_OTLP_PROTOCOL=grpcにより有効化できます。

TypeScript 6

Deno本体に組み込まれたTypeScriptが5.9.2から6.0.3へアップデートされています (#32944)

V8 14.9

Deno本体のV8が14.9へアップデートされています (#34226)

これによりMath.sumPrecise()Intl.Locale.variantsが利用できます (#34287)

--unstable-raw-importsの安定化

Deno v2.4で実装されたwith { type: "text" }またはwith { type: "bytes" }によるテキスト/バイト形式でのimportが安定化されています。--unstable-raw-importsを指定せずにこれらの機能が利用可能です。

Node.js互換性の改善

Deno v2.8.0では、既存の各種Node.js組み込みモジュール (node:*) に対して膨大な量のコミットが実施されており、公式ブログによると、Node.jsのテストスイートにおける70%以上のテストが成功する程度にまで互換性が改善されたようです。

すべての変更を紹介することは難しいため、主要と思われる変更のみ紹介いたします。

--node-modules-linker

--node-modules-linkerオプションが追加されています (#32788)。

これはpnpmにおけるnodeLinkerオプションに相当するオプションで、現状ではhoistedまたはisolatedのいずれかの値の指定がサポートされています。

デフォルト値はisolatedで、isolatedが指定されている際はpnpmなどと同様のレイアウトでnode_modulesが作成されます (既存の挙動)

hoisted (--node-modules-linker=hoisted) を指定すると、DenoがnpmやYarn v1と同様のレイアウトでnode_modulesを作成してくれます (--node-modules-dir=manualとの併用が必要です)

また、本オプションはdeno.jsonにおけるnodeModulesLinkerによって設定することも可能です。

このオプションの追加によりnpmを採用したプロジェクトとの互換性が改善されそうです。

min-release-age

.npmrcにおけるmin-release-ageがサポートされています (#33983)

deno.jsonにおいてminimumDependencyAgeがすでに設定されている場合は、minimumDependencyAgeの方が優先されます。

NODE_EXTRA_CA_CERTS

NODE_EXTRA_CA_CERTSがサポートされています (#33148)

Node.js向けのAPIだけでなく、fetch()などに対しても効果が適用されます。

Deno.upgradeWebSocket()

Deno.upgradeWebSocket()socketオプション及びheadオプションが追加されています (#33342)

これらのオプションにServerオブジェクト (node:http) の'upgrade'イベントで通知されたstream及びheadパラメーターを指定することにより、WebSocketへのアップグレードが可能です。

(#33342) によると、Viteのdevサーバー (例: @fresh/plugin-vite) などでの活用が想定されているようです。

node:wasi

node:wasiの実装が追加されています (#34089, #34245)

Denoのパーミッションシステムと統合されており、preopensに指定された各種パスに対して権限が付与されているかを確認してくれるようです。

node:module

registerHooks()が実装されています (#34081, #34219, #34223)。Denoがモジュールを読み込む際の振る舞いをカスタマイズできます。

また、下記APIも実装されています:

  • SourceMap/findSourceMap() (#32890)
  • enableCompileCache()/flushCompileCache()/getCompileCacheDir() (#34190)

node:inspector

ネットワーク関連のCDPサポートが拡充されています (#32707, #34201, #34204, #34220, #34222, #34231, #34270)

これにより、--inspectを使用した際に、Denoがfetch()node:httpなどを介して実行したHTTPリクエストがChrome DevToolsから閲覧できるように改善されているようです。

node:sqlite

DatabaseSyncの下記APIが実装されています:

  • limitsプロパティー (#33106)
  • serialize()/deserialize()メソッド (#34010)

node:test

下記APIが実装されています:

  • expectFailure()及びexpectFailureオプション (#34130)
  • TestContext の下記プロパティ及びメソッド (#33764)
    • name
    • fullName
    • signal
    • plan()
    • beforeEach()
    • afterEach()
  • mock.getter()/mock.setter()/MockFunctionContext#mockImplementation()/MockFunctionContext#mockImplementationOnce() (#33755)
  • before()/after()/beforeEach()/afterEach() (#33929)
  • run()の部分的サポート (watch/cwd/signalオプションがサポート) 及び TestsStream'test:watch:drained'/'test:watch:restarted'が実装 (#34254)

node:v8

下記APIが実装されています:

node:fs

watch()encoding及びsignalオプションが実装されています (#33634, #33650)

node:net

下記APIが実装されています:

  • SocketAddress (#34020)
  • connect()onreadオプション (#34164)

node:http

createServer()の下記オプションがサポートされています:

node:http2

下記APIが実装されています:

  • performServerHandshake() (#33668)
  • createServer()maxSettingsオプション (#33790)
  • maxOutstandingPingsオプション (#33791)

node:tls

下記APIが実装されています:

  • getCACertificates() (#32032)
  • createServer()ALPNCallback及びSNICallbackオプション (#33360)

node:process

getActiveResourcesInfo()が実装されています (#34101)

node:perf_hooks

createHistogram()が実装されています (#34003)

node:trace_events

createTracing(options)及びgetEnabledCategories()の互換性が改善されています (#34216)

node:worker_threads

postMessageToThread()が実装されています (#34015)

node:util

aborted()resource引数がサポートされています (#34142)

node:crypto

createPublicKey()/createPrivateKey()/createSecretKey()の引数としてCryptoKeyの指定がサポートされています (#33750)

また、createCipheriv()及びcreateDecipheriv()で下記アルゴリズムがサポートされています (#33813)

  • aes128-wrap
  • aes192-wrap
  • aes256-wrap
  • id-aes128-wrap-pad
  • id-aes192-wrap-pad
  • id-aes256-wrap-pad

パフォーマンス改善

node:httpのパフォーマンスが改善されています (#33860)。公式ブログによるとおおよそ2倍程度まで改善されるケースもあるようです。

また、V8のスレッドプールに対して今まではシステムで利用可能なコア数を元にサイズが決定されていましたが、最大で4に設定するように変更されています (#33697)。Node.jsも同様の設定で動作しているようで、それに合わせた変更のようです。これにより、小さなスクリプトを実行するようなケースにおけるリソース消費が効率化されるようです。

それ以外にもTextEncoder#encodeInto()のパフォーマンス改善なども行われています (#33675, #34055)

参考