2024年のDenoのまとめと今後について
はじめに
Denoアドベントカレンダー 23日目の記事です🎅
この記事では、2024年にDenoやその周辺に関する変更点などをまとめます。
Deno
Deno v2のリリース
Deno v2が正式にリリースされました:
Deno v2の正式リリースに伴い、Deno v2.1からLTSリリースが開始されています。
また、Deno for Enterpriseというサービスが正式に発表されました (主にエンタープライズ向けにDenoランタイムに関するSlackでのサポートなどが提供されるサービスのようです)
Node.js互換性の大きな改善 (Next.jsのサポートなど)
Next.jsのサポート
DenoにおけるNode.js互換性の改善に伴い、Next.jsが動作するようになったようです。Denoの公式ドキュメントなどにおいてNext.jsのチュートリアルが公開されています。
また、Deno公式から@deno/nextjs-startというJSRパッケージが公開されています。このパッケージを使うことで、Deno DeployでNext.jsアプリケーションを動作させられるようです。
--allow-scripts
- ライフサイクルスクリプトのサポート
セキュリティに関する懸念から、Denoにおいてはnpmパッケージに含まれるライフサイクルスクリプトの実行がサポートされていませんでした。
しかし、一部のnpmパッケージを動作させるためには、ライフサイクルスクリプトのサポートが必要になります。そこで、Deno v1.45から--allow-scripts
オプションが追加されました。この--allow-scripts
によって許可されたパッケージに対してのみ、限定的にライフサイクルスクリプトの実行が許可されます。
deno install
によって依存パッケージをインストールする際などに--allow-scripts
にパッケージを指定することで、指定されたパッケージに含まれるライフサイクルスクリプトを実行することができます:
$ deno install --allow-scripts=npm:duckdb@1.0.0 npm:duckdb@1.0.0
CommonJSサポートの改善
Denoにおいて.cjs
/.cts
モジュールの実行やimport
がサポートされています。
また、package.json
で"type": "commonjs"
が定義されているパッケージで.js
ファイルをCommon JSモジュールとして読み込めるようにする機能が実装されています。この機能を利用する際は、node_modules
が自動で作成されるよう、deno.json
で"nodeModulesDir": "auto"
の設定が推奨されます。
deno init --npm
これはnpm create
などに相当するコマンドで、npmに公開されたcreate-<package名>
パッケージを実行することができます。
例えば、以下のコマンドを実行すると、Denoで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 task
- package.json
で定義されたスクリプトとnpmバイナリの実行がサポート
deno task
コマンドにpackage.json
のscripts
などを認識してくれる機能が導入されています:
# 1) package.jsonを作成します
$ echo '{ "scripts": { "hi": "cowsay hi" } }' > package.json
# 2) npmパッケージをインストールします (package.jsonがあるため、そちらへ依存が追加されます)
$ deno add --dev npm:cowsay
# 3) npmパッケージがインストールされました
$ cat package.json
{
"scripts": { "hi": "cowsay hi" },
"devDependencies": {
"cowsay": "^1.6.0"
}
}
# 4) deno taskでnpmバイナリを実行します
$ deno task hi
Task hi cowsay hi
____
< hi >
----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
--unstable-node-globals
このオプションを指定すると、DenoにおいてNode.jsの各種グローバルAPIが有効化されます。
console.info(setImmediate);
このスクリプトを--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]
.npmrcのサポート
Deno v1.44から.npmrc
のサポートが追加されています。現時点では認証に関する設定などがサポートされています。
npm Workspacesのサポート
DenoにおいてNode.jsプロジェクトの動作を行いやすくするため、npm Workspacesのサポートが追加されています。Denoがpackage.json
のworkspaces
キーを認識してくれます。
JSR
Deno公式ブログでJSRというパッケージレジストリが発表されました。
JSRはDenoだけでなく、jsr-npm
を使用することでNode.jsやBunなどの様々なランタイムもサポートすることが想定されています。
Denoにおいてはjsr:
URLによってJSRで公開されたパッケージを読み込むことができます。
import { assertEquals } from "jsr:@std/assert@1/equals";
assertEquals(sum(1, 2), 3);
assertEquals(sum(), 0);
JSRの開発は以下のリポジトリで行われています:
WASMモジュールのサポート
最近、リリースされたDeno v2.1ではWASMモジュールのサポートが追加されています。以下のように、JavaScript/TypeScriptコードから.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 add
Deno v1.41.1でdeno add
というコマンドが実装されています。npmパッケージやJSRパッケージをdeno.json
やpackage.json
に依存関係として追加する際に利用することができます。また、deno.lock
の更新も行ってくれます。
# npmパッケージをインストールします
$ deno add npm:chalk@5.3.0
# jsrパッケージをインストールします
$ deno add jsr:@oak/oak
deno remove
deno remove
という新しいコマンドが追加されています。これはdeno.json
のimports
もしくはpackage.json
から指定したパッケージを削除し、deno.lock
を更新してくれるコマンドです。
# deno.jsonのimports 及び deno.lock から指定したパッケージを削除します
$ deno remove @deno/otel
# package.jsonで定義された依存パッケージも削除できます
$ deno remove cowsay
deno install
の振る舞いの変更
元々、deno install
コマンドはDenoで書かれたスクリプトやCLIツールをインストールするためのコマンドという位置づけでした (Goにおけるgo install
に近いイメージです)
Deno v2のリリースに伴いdeno install
コマンドの振る舞いが変更され、デフォルトではdeno add
コマンドのエイリアスとして機能します:
# JSRから@oak/oakパッケージをインストールします
$ deno install jsr:@oak/oak
引数なしでdeno install
を実行した場合は、プロジェクトが依存しているパッケージの一覧をインストールしてくれます。(npm install
などと同様に動作するように変わったイメージです)
もしDeno v1の頃と同様の振る舞いをさせたい場合は、--global
オプションを指定する必要があります。
$ deno install --global --allow-read=. --allow-write=. --allow-net https://deno.land/x/udd/main.ts
また、deno install
に--entrypoint
が追加されています。--entrypoint
が指定された場合、deno cache
コマンドと同様の振る舞いをします。(これに合わせて、deno cache
コマンドは非推奨化されています)
# main.tsを動作させるために必要なリモートモジュールがダウンロードされます
$ deno install --entrypoint main.ts
deno uninstall
コマンドの振る舞いの変更
deno uninstall
コマンドは元々、deno install
コマンドによってインストールされたスクリプトを削除するためのコマンドでした。
このdeno uninstall
コマンドについてもdeno install
コマンドと同様に、deno remove
コマンドのエイリアスとして機能するようデフォルトの振る舞いが変更されています。
# @deno/otelパッケージをdeno.jsonのimportsから削除します
$ deno uninstall @deno/otel
もしdeno uninstall
コマンドを今までの挙動に戻したい場合は--global
または-g
オプションを指定する必要があります。
deno outdated
deno outdated
という新しいコマンドが実装されています。このコマンドには2つの役割があり、まず1つ目として、プロジェクトが依存しているパッケージに関する最新情報などを表示できます:
$ 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 │
└────────────────────┴─────────┴────────┴────────┘
2つ目の役割として、--update
オプションを併用することで、プロジェクトが依存しているパッケージのバージョンを更新することができます:
# deno.jsonで指定されたバージョンレンジに基づいて指定されたパッケージを更新する
$ deno outdated --update "@nestjs/*"
# バージョンを明示する
$ deno outdated --update @nestjs/common@^10.4.8 @nestjs/core@^10.4.8
# バージョンレンジに関わらず、常に最新バージョンへアップデート
$ deno outdated --update --latest "@nestjs/*"
ワークスペース
Denoのワークスペース機能が正式にリリースされました。以下のようにdeno.json
のworkspace
でワークスペースに関する設定が行えます:
{
"workspace": {
"members": ["./packages/*"]
},
"imports": {
"@david/dax": "jsr:@david/dax@0.42.0"
}
}
ワークスペースのメンバーとして扱う各パッケージについてもname
/version
/exports
の3つを定義したdeno.json
を用意する必要があります:
{
"name": "@uki00a/foo",
"version": "0.1.0",
"exports": { ".": "./mod.ts" },
"imports": {
"@std/csv": "jsr:@std/csv@^1"
}
}
各ワークスペースメンバー間においては、deno.json
のname
で定義された名前で参照することができます:
import { foo } from "@uki00a/foo";
このワークスペース機能の利点として、このようにdeno.json
を複数定義することができるため、各ワークスペースメンバーごとに独自のImport mapsを定義することができます。ワークスペースのルートで定義されたImport mapsは全メンバーに適用されます。また、後述するdeno task
コマンドにおいて、ワークスペースの複数のメンバーに対して一括でタスクを実行する機能が導入されています。
deno test --doc
でコードブロックの実行がサポート
今まで、deno test --doc
コマンドではMarkdownファイルやJSDocコメント中のTypeScriptコードブロックの型チェックのみがサポートされていました。Deno v2のリリースに伴ってdeno test --doc
が拡張され、コードブロックのテストもサポートされました。
/**
* ```typescript
* import { assertEquals } from "jsr:@std/assert@1/equals";
*
* assertEquals(sum(1, 2), 3);
* assertEquals(sum(), 0);
* ```
*/
export function sum(...numbers: Array<number>): number {
return numbers.reduce((a, b) => a + b, 0);
}
以下のようにJSDocコメントに記述されたコードブロックが実行されます:
$ deno test --doc ./sum.ts
Check file:///home/uki00a/ghq/github.com/uki00a/deno-sandbox/sum.ts
Check file:///home/uki00a/ghq/github.com/uki00a/deno-sandbox/sum.ts$2-8.ts
running 0 tests from ./sum.ts
running 1 test from ./sum.ts$2-8.ts
file:///home/uki00a/ghq/github.com/uki00a/deno-sandbox/sum.ts
$2-8.ts ... ok (0ms)
ok | 1 passed | 0 failed (32ms)
deno fmt
- YAML/HTML/CSS/Vue/Svelte/Astro/SQLのサポート
deno fmt
コマンドでは、今まではTypeScriptやJavaScript, Markdownなどがサポートされていました。
今年はdeno fmt
のサポート対象の言語が大幅に拡張され、以下の言語もサポートが追加されました (一部の言語についてはまだ実験的サポートの段階であるため、--unstable-*
オプションの指定が必要です):
- YAML
- CSS
- LESS
- Sass
- SCSS
- HTML
- Svelte (利用には
--unstable-component
の指定が必要です) - Vue (利用には
--unstable-component
の指定が必要です) - Astro (利用には
--unstable-component
の指定が必要です) - Angular (利用には
--unstable-component
の指定が必要です) -
Nunjucks (利用には
--unstable-component
の指定が必要です) -
Vento (利用には
--unstable-component
の指定が必要です) - SQL (利用には
--unstable-sql
の指定が必要です)
deno fmt
/deno lint
- .gitignore
のサポート
deno fmt
とdeno lint
で.gitignore
がサポートされました。.gitignore
で指定したファイルはデフォルトでフォーマットやLintの対象から除外されます。
deno lint
- Quickfixのサポート
一部のLintルールでQuickfixがサポートされています。deno lint
に--fix
オプションが指定された場合、修正可能な問題が検出された際に自動で修正を行ってくれます:
$ deno lint --fix main.js
deno lint
- no-console
ルールがサポート
ESLintに存在する同名のルールと同様に、console.log
などの使用を検出してくれます。deno.json
で以下のように設定しておくと有効化できます:
{
"lint": {
"rules": { "include": ["no-console"] }
}
}
deno jupyter
の安定化
Deno v1.40からdeno jupyter
コマンドが安定化されています。現在は--unstable
を指定せずに利用することができます。
deno serve
deno serve
という新しいコマンドが追加されています。deno serve
を利用するためには、以下のようにDeno.ServeDefaultExport
を実装したオブジェクトをdefault export
するファイルを用意します:
export default {
fetch(req) {
return new Response("OK");
},
} satisfies Deno.ServeDefaultExport;
その後、このファイルを引数に指定してdeno serve
を実行すると、default export
されたDeno.ServeDefaultExport
オブジェクトに基づいてHTTPサーバーを起動してくれます:
$ deno serve main.ts
$ curl http://localhost:8000/
OK
deno serve
コマンドの大きなメリットとして、--parallel
オプションを指定することで、利用可能なコア数に基づいて内部で複数のワーカーを起動して負荷分散を行ってくれる機能があります (ワーカー数はDENO_JOBS
環境変数によって調整することも可能です)
$ DENO_JOBS=2 deno serve --parallel main.ts
deno serve: Listening on http://0.0.0.0:8000/ with 2 threads
deno task
- タスク間の依存関係の定義がサポート
wireitを参考に、タスク間の依存関係の定義がサポートされました。以下のように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:fmt
とcheck:deno-json
タスクが並列で実行され、それらが成功した場合のみcheck:all
のcommand
が実行されます。
dependencies
を持つタスクに関しては、おそらく次にリリースされるであろうDeno v2.2あたりでcommand
の指定が省略可能になると思われます:
deno task
- ワークスペースのサポート
deno task
コマンドに--filter
及び--recursive
オプションが追加されています。--filter
オプションが指定された場合、該当の名前にマッチするメンバーのdeno.json
で定義されたタスクをまとめて実行することができます:
# 名前が`platform-*`パターンにマッチするメンバーのhiタスクを実行
$ deno task --filter 'platform-*' hi
# すべてのメンバーのhiタスクを実行
$ deno task --filter '*' hi
--recursive
オプションについては、実質的に--filter *
と同様に動作します:
# ワークスペース内の各パッケージで定義されたtestタスクを実行します
$ deno task --recursive test
deno clean
コマンド
deno clean
という新しいコマンドが追加されています。現状ではDenoのグローバルキャッシュ(DENO_DIR
)の削除のみがサポートされています。
deno <entrypoint>
Deno v1.46からdeno run
コマンドにおけるrun
の指定を省略できるようになりました:
# `deno run --allow-read main.ts`と同様に動作します
$ deno --allow-read main.ts
パーミッションフラグの短縮形式
各種--allow-*
オプションについて短縮形式がサポートされています:
パーミッションフラグ | 短縮形 |
---|---|
--allow-read |
-R |
--allow-write |
-W |
--allow-net |
-N |
--allow-env |
-E |
--allow-sys |
-S |
例えば、以下はdeno run --allow-read --allow-env main.ts
と同等です:
$ deno -ER main.ts
--allow-import
の導入
Deno v2のリリースに伴い、--allow-import
(-I
)という新しいパーミッションフラグが導入されています。
Deno v2からはリモートモジュールの読み込みを許可するホストに制限がかかります。必要に応じて--allow-import
にリモートモジュールの読み込みを許可するホストを指定する必要があります。ただし、デフォルトでは以下のホストからのモジュールのimport
が許可されているため、基本的なケースにおいては今まで通り利用できると思われます:
上記以外のホストからモジュールをimport
したい場合、--allow-import
の指定が要求されます。例えば、unpkg.comからモジュールをimport
しようとすると権限が要求されます:
import ky from "https://unpkg.com/ky@1.7.2";
const res = await ky.get("https://api.github.com/repos/uki00a/deno-weekly").json();
以下のように--allow-import
によって明示的に許可することでimport
できます:
$ deno run --allow-net --allow-import=unpkg.com main.js
--allow-env
- 特定の名前で始まる環境変数の一括許可がサポート
--allow-env
オプションにおいて、以下のようにプレフィックスを指定することで、特定の環境変数へのアクセスを一括で有効化することがサポートされました:
# 名前が`APP_`から始まる環境変数の参照を許可します
$ deno run --allow-env='APP_*' main.js
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_TRACE_PERMISSIONS
によって有効化されるスタックトレースの収集は高価な処理のため、この機能は本番環境などにおいては無効化することが推奨されます。
--frozen-lockfile
--frozen-lockfile
という新しいオプションが導入されています。このオプションが指定された場合、あるパッケージに関してdeno.lock
で指定されているバージョンと実際に使用されているバージョンが異なる場合にエラーが発生します。CIにおいて利用するとよさそうです。
$ deno test --allow-net --no-check --frozen-lockfile ./test
deno compile
- ローカルファイル/ディレクトリの埋め込みがサポート (--include
)
実行可能ファイルへのローカルのファイル/ディレクトリの埋め込みがサポートされています。
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
denort
(deno compile
向けの軽量バイナリ)の再導入
Deno v1.40.5において3年前に削除(#10350)されていたdenort
バイナリが改めて導入されました。これによってdeno compile
によって生成される実行可能ファイルのサイズが2分の1ほどまで軽量化されています。
GitHub Releasesに各プラットフォーム向けのdenort
バイナリーがアップロードされており、deno compile
を実行する際に自動でダウンロードされます。
Deno v1.41の公式ブログ記事によると、deno compile
をする際に特定の機能のみを有効化したカスタムビルドをサポートすることで、さらにバイナリを軽量化する機能を将来的に導入することなども検討されているようです。
External WebGPU surfaces / BYOW (Bring your own Window)
Deno v1.40からDeno.UnsafeWindowSurface
というAPIが追加されています。
deno_sdl2@0.8.0などではこの機能のサポートが追加されていて、これによりWebGPUを活用して高速にレンダリングが行えるようです。
この機能を活用したwgui
というフレームワークも開発されているようです:
Deno.telemetry
)
OpenTelemetryサポート (Deno v2.1からOpenTelemetryサポートが実験的に追加されています。20日目の記事で内容を書いたので、もしご興味がありましたら参照いただければと思います。
Deno.errors.NotCapable
Deno.errors.NotCapable
という新しいエラーが導入されています。今までは、OSによる権限エラーとDenoによる権限エラー(--allow-*
の指定漏れ)の両方がDeno.errors.PermissionDenied
によって表現されていましたが、それらをきちんと区別できるようにするために、Denoの権限エラーはDeno.errors.NotCapable
によって表現されるよう変更されています。
Temporal
のサポート
Deno v1.40からTemporal
のサポートが実験的に追加されています。
利用するには--unstable-temporal
またはdeno.json
で"unstable": ["temporal"]
の指定が必要です。
compilerOptions.jsxImportSourceTypes
Deno v1.43で導入されたTypeScriptに関する独自のオプションです。
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "npm:react@18.3.1",
"jsxImportSourceTypes": "npm:@types/react@18.3.1"
}
}
このオプションが導入された背景についてですが、まずJSX Transformが有効化された場合、TypeScriptは<some-jsx-package>/jsx-runtime
をimport
するようなコードを生成します:
// 例) Reactの場合、以下のようなコードが生成されます
import {jsx as _jsx} from 'react/jsx-runtime';
// ...
元々、Denoにはこの<some-jsx-package>/jsx-runtime
のimport
に対して適用すべき型定義を判断する方法が存在せず、JSX Transformを有効化してReactなどを使う場合に型エラーが発生する課題がありました。TypeScriptによって自動生成されるコードのため@ts-types
プラグマ(旧@deno-types
)を適用することもできませんでした。
compilerOptions.jsxImportSourceTypes
はこの課題を解消するために導入されたもので、上記のような<some-jsx-package/jsx-runtime
のimport
に対して、Denoがどの型定義を適用すればよいか判断できるようになります。
@ts-types
と@ts-self-types
プラグマ
@ts-types
と@ts-self-types
という新しいプラグマが導入されています。
@ts-types
については@deno-types
プラグマと同様に、特定のJavaScriptモジュールに対して型定義を適用したい場合に指定することが想定されているようです。今後は@deno-types
ではなく@ts-types
の方の使用が推奨されるようです。
// @ts-types="./add.d.ts"
import { add } from "./add.js";
@ts-self-types
についてもJavaScriptで書かれたモジュールに型を適用するための機能のようですが、実質的に/// <reference types="..." />
と同様に動作するようです。JavaScriptモジュールに対して型を適用したいケースを除いて、/// <reference types="..." />
の方の使用が推奨されるようです。
// @ts-self-types="./globals.d.ts"
deno lsp
のパフォーマンス改善
Deno v1.43においてdeno lsp
のパフォーマンスが大幅に改善されています。今までは巨大なプロジェクトにおいては自動補完に6〜8秒程時間がかかることもあったようですが、現在は1秒以内に収まる程度まで高速化されているようです。
Deno本体においてdeco-cx/appsを使用したベンチマークの仕組みも導入されており、これによってパフォーマンスが計測されているようです。
V8コードキャッシュ
V8が生成したコードキャッシュを保存することで、Denoの起動を高速化する仕組みが導入されています。DENO_DIR
配下にv8_code_cache_v2
というSQLiteデータベースファイルが作られ、そこで生成されたV8コードキャッシュが管理されます。
この仕組みはデフォルトで有効化されており、--no-code-cache
によって無効化できます。
deno compile
におけるサポートについて
このV8コードキャッシュの仕組みはdeno compile
で生成される実行可能ファイルにおいてもサポートされています。
deno compile
においては通常のケースとは異なり、deno compile
によって作成された実行可能ファイルの初回実行時に/tmp
ディレクトリ配下にV8コードキャッシュが保存されます。実行可能ファイルを2回目以降に実行する際に、/tmp
ディレクトリに保存されたV8コードキャッシュが読み込まれます。
deno compile
によって生成された実行可能ファイルが保存したV8コードキャッシュのパスについては、DENO_LOG=debug
を指定することで確認できます:
$ DENO_LOG=debug ./sample
... 省略 ...
DEBUG RS - denort::standalone::code_cache:45 - Loaded 1 code cache entries from /tmp/deno-compile-sample.cache
... 省略 ...
deno bundle
コマンドの削除
非推奨化されていたdeno bundle
コマンドが削除されています。
deno_emitやesbuildなどへの移行が推奨されています。
deno vendor
コマンドが削除
非推奨化されていたdeno vendor
コマンドが削除されました。
deno.json
で"vendor": true
または--vendor
を指定することで同様のことが実現できるため、今後はそちらなどへの移行が推奨されます。
非推奨APIの削除
Deno v2のリリースに伴い、様々な非推奨APIが削除されています。公式でマイグレーションガイドが公開されており、移行先などについて解説されています。
Denoの今後について
Denoにおいて直近で進められている開発内容についていくつか紹介いたします。
QUICとWebTransport APIのサポート
まず、直近でQUICに関するサポートがDeno本体のmain
ブランチにすでにマージされています。
Deno.connectQuic
やDeno.listenQuic
などのAPIが実装されており、利用するには--unstable-net
の指定が必要になる想定です。おそらく、QUICのサポートに関しては間もなくリリースされると思われるDeno v2.2あたりでリリースされるのではないかと思います。
また、このQUICの実装をベースにWebTransport APIを実装するPRも作成されています。
このPRはまだマージはされていませんが、WebTransport APIの実装に加えて、Deno.upgradeWebTransport
というWebTransportサーバーを立てるための独自のAPIも実装されているようです。(これらのAPIについても、使用には--unstable-net
の指定が必要になります)
deno lint
でのJavaScriptプラグインのサポート
まだマージはされておらず正式に導入されるかどうかはわかりませんが、deno lint
においてJavaScriptでプラグインを記述するための機能を実装するPRが作成されています:
直近ではJavaScriptプラグインを実行するためのDeno[Deno.internal].runLintPlugin
という内部APIを実装するPRがDeno本体のmain
ブランチへすでにマージされているようです。(まだCLIオプションや公開APIなどは追加されていないため、一般利用はできない状態です)
node:sqlite
Deno本体にnode:sqlite
パッケージを実装するPRが作成されています。
まだ正式に導入されるかどうかはわかりませんが、個人的には非常に便利なのではないかと思っています。
deno_std
(@std
)
deno_std
はDeno公式の標準ライブラリです。
JSRへの公開とv1のリリースについて
まず、deno_std
に関する大きな変更として、JSRへのパッケージの公開が実施されました:
今後はhttps://deno.land/stdではなくjsr:@std経由での利用が推奨されます。
JSRにdeno_std
が公開されたことにより、deno_std
を構成する各パッケージごとに独立してバージョン管理ができるようになりました。
これによって、deno_std
においてすでに安定しているパッケージについてはv1がリリースされています。
例)
パッケージの運用について
v1がリリースされていないパッケージについては、既存のAPIに対して破壊的変更が発生する可能性があります。
すでにv1がリリースされているパッケージに新規APIを追加する際は、unstable-
プレフィックスつきのモジュールから公開されます (例: @std/http/unstable-route)
このunstable-
がついたモジュールから公開されるAPIについては、破壊的変更が実施される可能性があります。
@std/http/unstable-route
- 軽量なルーティングモジュール
HTTP関連のパッケージである@std/httpに軽量なルーティング用モジュールが実験的に追加されています:
import type { Route } from "jsr:@std/http@1/unstable-route";
import { route } from "jsr:@std/http@1/unstable-route";
const routes: Array<Route> = [
{
pattern: new URLPattern({ pathname: "/messages/:id" }),
handler: (
_req,
params,
) => new Response(`Message ${params?.pathname.groups.id}`),
},
{
pattern: new URLPattern({ pathname: "/authenticate" }),
method: "POST",
handler: () => new Response("OK"),
},
];
const defaultHandler = (req: Request) =>
new Response("Not Found", { status: 404 });
const handler = route(routes, defaultHandler);
export default {
fetch: (req) => handler(req),
} satisfies Deno.ServeDefaultExport;
deno serve
あたりと併用して、ちょっとしたWebアプリケーションを実装したい場合などに便利そうです。
@std/uuid/unstable-v7
- UUIDv7の実験的サポート
UUIDに関する機能を提供する@std/uuidでUUIDv7の実験的サポートが追加されています。
import { generate } from "jsr:@std/uuid@1/unstable-v7";
console.info(generate());
新規パッケージ
以下のような新規パッケージがdeno_std
に追加されています:
パッケージ | 説明 |
---|---|
@std/cache |
関数のメモ化などの機能が提供されます |
@std/tar |
tarに関するユーティリティーです (これの追加に伴い、@std/archive は削除されました) |
@std/random |
乱数の生成や配列のシャッフルなどのユーティリティーが提供されます |
@std/cbor |
CBORの実装です |
Fresh v2
FreshはDeno公式のPreactベースのメタフレームワークです:
現在、Freshではv2の開発が進められており、v2のアルファバージョンが公開されています。
また、先程紹介したJSRにおいては、すでにFresh v2のアルファバージョンが採用されています。
Fresh v2での変更内容などについては以下のページにまとめています:
Deno Deploy
Deno DeployはDenoが提供しているサーバーレスJavaScriptランタイムです:
Deno Deploy NextGen
Deno公式からDeno Deploy NextGenというものが公開されています:
まだ公式ブログなどでのアナウンスはされていないですが、これはKubernetesクラスター上でユーザーがDeno Deployのインフラストラクチャーを実行するための基盤のようで、現時点だとAWSとAzureがサポートされているようです。
Web Cache APIのサポート
Deno DeployにおいてWeb Cache APIのベータサポートが実施されています。
以下の記事ではHTTPヘッダーに基づいたキャッシュの有効期間の管理や内部の仕組み、料金設定などについて解説されています。
エコシステム
@deno/vite-plugin
Deno公式からViteプラグインが公開されています:
- パッケージ: @deno/vite-plugin
- リポジトリ: denoland/deno-vite-plugin
npm:
/jsr:
/https:
のサポートや、deno.json
で定義されたImport maps
の解決などがサポートされているようです。
@types/deno
DefinitelyTypedに@types/denoパッケージが追加されています:
DenoのAPIに関する型定義が提供されるようです。
@deno/kv-utils
Deno公式から提供されているDeno KVのユーティリティーパッケージです。
元々、kv-toolboxから提供されていた一部のAPIは、現在では@deno/kv-utils
から提供されています。
LumeCMS
LumeCMSというCMSが発表されています。
名前の通り、LumeというスタティックサイトジェネレーターではこのLumeCMSのサポートがデフォルトで提供されます。
Lumeと名前についていますが、アダプターを実装することによって様々なスタティックサイトジェネレーターと連携できるようにすることが想定されています。
Slint
GUIツールキットであるSlintのv1.4.0において、Denoのサポートが追加されています。
NativeScript
NativeScriptの公式ブログで@nativescript/macos-node-api
というパッケージが紹介されています。
このパッケージはNode.jsに加えてDenoでも動作するようです。
以下のリポジトリでは、このパッケージとNode.jsまたはDenoを使って、macOS向けのデスクトップアプリを作成する例が公開されています。
UnJSプロジェクト
UnJSにおいてDenoサポートを進めていくことが検討されているようです:
以前からDenoのサポートが進められていたNitro (v2.5.0)に加えて、現在ではcrosswsでもDenoのサポートが導入されているようです。
また、直近ではUnstorageにDeno KVドライバーの実装が追加されています:
jsr:@eslint/*
ESLint関連のパッケージがjsrへ公開されています:
@eslint/coreや@eslint/compat, @eslint/jsonなどのパッケージが公開されているようです。
Hono
Honoではv4.4.0からJSRへのパッケージの公開が行われています:
Oak
DenoのWebフレームワークであるOakについてはv14.1.0からNode.jsとCloudflare Workersのサポートが追加されています。
また、JSRパッケージも公開されています。
esm.sh
esm.shに関する大きな変更として、JSRのサポートが追加されています。
ブラウザーなどから直接JSRパッケージを読み込みたいケースなどで活用できそうです。
おわりに
今年はDeno v2のリリースやJSRの公開など、大きな変更がたくさんありました。
初期のころから要望が多くあったWASMモジュールのサポートが導入されたり、External WebGPU surfacesなどのよりユースケースを拡充するための機能なども導入されました。
今後、deno lint
におけるJavaScriptプラグインサポートやnode:sqlite
などが導入されるとさらに利便性が向上すると思われるため、個人的に非常に楽しみにしています。
Discussion