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

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

ワークスペース

先週紹介したワークスペースに関する改善が正式にリリースされました。

deno.jsonでワークスペースを定義するためのworkspacesキーがworkspaceにリネームされています。

また、オブジェクト形式でワークスペースに関する設定が定義できるようになりました (cli/schemas/config-file.v1.json#L607-L629)

{
  "workspace": {
    "members": ["./member1", "./member2"]
  }
}

現時点では設定項目としてworkspace.membersのみが存在しますが、今後、追加される可能性もありそうです。

このworkspace.membersにはdeno.jsonを含むディレクトリだけでなく、package.jsonを含むディレクトリをワークスペースのメンバーとして指定することもできるようです。

deno_stdでもすでに新しいフォーマットへ移行されているようです。

Node.js互換性の改善

npm workspacesのサポート

先週紹介したnpm workspacesに関するサポートが正式にDenoに導入されました。Denoがpackage.jsonworkspacesキーを認識してくれます。

以下のようなワイルドカード形式でのワークスペースメンバーの指定もサポートが導入されています。

{
  "workspaces": ["packages/*"]
}

また、deno publishコマンドでもnpm workspacesに関するサポートが導入されているようです。#24507によると、以下のような構成のプロジェクトにおいてdeno publishを実行すると、packages/member-1packages/member-2がJSRに公開されるようです。

  • project/
    • package.json ("workspaces": ["packages/*"]が設定)
    • packages/
      • member-1/
        • pakcage.json
        • jsr.json
      • member-2/
        • package.json
        • jsr.json

ライフサイクルスクリプトのサポート

deno cache またはDENO_FUTURE=1 deno installでライフサイクルスクリプトの実行がサポートされています。公式ブログでも紹介されているduckdb-nodeを例に使い方について紹介します。

まず、Denoはdeno cache またはDENO_FUTURE=1 deno installによってライフサイクルスクリプトを含むnpmパッケージがダウンロードされた際に、デフォルトではライフサイクルスクリプトを実行せずに以下のような警告を表示します。

$ deno cache npm:duckdb@1.0.0
warning: Packages contained npm lifecycle scripts (preinstall/install/postinstall) that were not executed.
    This may cause the packages to not work correctly. To run them, use the `--allow-scripts` flag with `deno cache`
    (e.g. `deno cache --allow-scripts=pkg1,pkg2 <entrypoint>`):
      npm:duckdb@1.0.0

--allow-scriptsオプションにパッケージ名を指定することで、対象のパッケージに限定してライフサイクルスクリプトの実行を許可することができます。

$ deno cache --allow-scripts=npm:duckdb@1.0.0 npm:duckdb@1.0.0

現時点での制限として、この--allow-scriptsが機能するためには"nodeModulesDir": trueが設定されている必要があります。

{
  "nodeModulesDir": true
}

.npmrc

Deno v1.44で導入された.npmrcサポートが改善され、ユーザーのホームディレクトリにある.npmrcの読み込みがサポートされました。

ただし、複数の.npmrcのマージはまだサポートされておらず、プロジェクトルート直下に.npmrcがある場合は、そちらがホームディレクトリのものよりも優先して読み込まれます

Node.js組み込みパッケージの改善

様々な改善が行われており、node-tapが動作するようになったようです。

  • node:fs: lutimeslutimesSyncが実装されています。
  • node:fs: lchownlchownSyncが実装されています。
  • node:http: ServerResponse#appendHeaderが実装されています。
  • node:http: ClientRequest#endを呼ぶまでHTTPリクエストが送信されない問題が修正されています。
  • node:http: Transfer-Encoding: chunkedを有効化した場合、サーバーがhangする問題が修正されています。
  • node:http: リクエストの送信前にClientRequest#destroyを呼ぶとエラーが発生する問題が修正されています。
  • node:http: ServerResponse#writeHeadで未実装だったwriteHead(status: number, headers: Record<string, string> = {}): this以外のシグネチャがサポートされています。
  • node:crypto: Hashが再実装され、様々なハッシュアルゴリズムのサポートが追加されているようです (#24302)
  • node:assert: assert.throwsの2つめの引数にErrorコンストラクタが与えられた際に、throwされたエラーが該当クラスのインスタンスであることがチェックされるように改善されました。
  • node:zlib: リソースリークが修正されています。
  • node:process: getegidが実装されています。

その他

--allow-sysnode:fsnode:os, node:processなどの各API向けにパーミッションが追加されています。

  • username
  • cpus
  • homedir
  • statfs
  • getPriority
  • setPriority

また、npmパッケージの外部でBufferなどのNode.jsのグローバルAPIを参照した際に、エラーが発生せずにundefinedが返却される問題が修正されています。

CLI

--frozen/--frozen-lockfileオプションが追加

DenoにCIなどでの利用が想定された--frozen(--frozen-lockfile)オプションが追加されています。このオプションが指定された場合、deno.lockの内容と実際に使用されているパッケージのバージョンに差異がある場合にエラーが発生します。もし--frozenオプションによってエラーが発生した際は、deno.lockを更新する(--frozen=false)かまたは使用する依存パッケージのバージョンをdeno.lockで指定されたバージョンにあわせると解消するはずです。

$ deno test --allow-net --no-check --frozen-lockfile ./test

バージョンが合わない場合は、以下のようなエラーが発生します。

error: The lockfile is out of date. Run `deno cache --frozen=false` or rerun with `--frozen=false` to update it.
changes:
 24 | -      "npm:@nestjs/common@^10.3.9": "npm:@nestjs/common@10.3.9_reflect-metadata@0.2.2_rxjs@7.8.1",
 24 | +      "npm:@nestjs/common@^10.3.10": "npm:@nestjs/common@10.3.10_reflect-metadata@0.2.2_rxjs@7.8.1",
 25 | -      "npm:@nestjs/core@^10.3.9": "npm:@nestjs/core@10.3.9_@nestjs+common@10.3.9__reflect-metadata@0.2.2__rxjs@7.8.1_reflect-metadata@0.2.2_rxjs@7.8.1",
 25 | +      "npm:@nestjs/core@^10.3.10": "npm:@nestjs/core@10.3.10_@nestjs+common@10.3.10__reflect-metadata@0.2.2__rxjs@7.8.1_reflect-metadata@0.2.2_rxjs@7.8.1",
125 | -      "@nestjs/common@10.3.9_reflect-metadata@0.2.2_rxjs@7.8.1": {
125 | +      "@nestjs/common@10.3.10_reflect-metadata@0.2.2_rxjs@7.8.1": {
126 | -        "integrity": "sha512-JAQONPagMa+sy/fcIqh/Hn3rkYQ9pQM51vXCFNOM5ujefxUVqn3gwFRMN8Y1+MxdUHipV+8daEj2jEm0IqJzOA==",
126 | +        "integrity": "sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==",
131 | -          "tslib": "tslib@2.6.2",
131 | +          "tslib": "tslib@2.6.3",
135 | -      "@nestjs/core@10.3.9_@nestjs+common@10.3.9__reflect-metadata@0.2.2__rxjs@7.8.1_reflect-metadata@0.2.2_rxjs@7.8.1": {
135 | +      "@nestjs/core@10.3.10_@nestjs+common@10.3.10__reflect-metadata@0.2.2__rxjs@7.8.1_reflect-metadata@0.2.2_rxjs@7.8.1": {
136 | -        "integrity": "sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==",
136 | +        "integrity": "sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==",
138 | -          "@nestjs/common": "@nestjs/common@10.3.9_reflect-metadata@0.2.2_rxjs@7.8.1",
138 | +          "@nestjs/common": "@nestjs/common@10.3.10_reflect-metadata@0.2.2_rxjs@7.8.1",
145 | -          "tslib": "tslib@2.6.2",
145 | +          "tslib": "tslib@2.6.3",
221 | -          "tslib": "tslib@2.6.2"
221 | +          "tslib": "tslib@2.6.3"
234 | -      "tslib@2.6.2": {
234 | +      "tslib@2.6.3": {
235 | -        "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
235 | +        "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
261 | -      "npm:@nestjs/common@^10.3.9",
261 | +      "npm:@nestjs/common@^10.3.10",
262 | -      "npm:@nestjs/core@^10.3.9"
262 | +      "npm:@nestjs/core@^10.3.10"

deno init --lib

deno init--libオプションが追加されました。このオプションはJSRパッケージ向けのプロジェクトを作成したい場合に使用されることが想定されていて、下記の3ファイルのみが含まれるプロジェクトが作成されるようです。

  • deno.json
  • mod.ts
  • mod_test.ts

deno compile --env

deno compile--envオプションがサポートされています。このオプションを指定すると、.envファイルで宣言された環境変数がdeno compileによって生成されるバイナリーの中に埋め込まれます。

deno compileによって生成されたバイナリーでDeno.env.getが呼ばれた場合、--envオプションによってバイナリーに埋め込まれた環境変数がある場合はそれが返却されます。

この--envを指定した場合、.envで宣言された変数がバイナリーの中に埋め込まれるため、機密情報などは含めないように取り扱いには注意が必要そうです。

deno jupyter

Jupyter Notebook (deno jupyter)でpromptconfirmがサポートされています。こちらについてはDenoの公式ブログに動画があるため、そちらを参照いただくとイメージしやすいかと思います。

また、公式ブログによると、今後、deno jupyterでJSXなどによってインタラクティブなウィジェットを作成できるようにすることなども検討されているようです。

deno test

deno testコマンドでJestなどと同様に__tests__ディレクトリに配置されたテストファイルが検出されるように改善されています。

deno lsp

deno lspにおける複数のdeno.jsonの取り扱いが改善されています。具体的には、検出された各deno.jsonごとに、型チェックや依存解決などの挙動が分離されたようです。

TypeScript v5.5

Deno本体に組み込まれているTypeScriptのバージョンがv5.5.2へアップデートされています。Inferred Type Predicatesなどの機能が利用できるようになりそうです。

破壊的変更

--lock-writeの非推奨化

--frozen(--frozen-lockfile)オプションの導入に合わせて、--lock-writeが非推奨化されました。

--lock-writeと同様のことを行いたい場合は、今後は--frozen=falseを指定する必要があります。

deno vendorコマンドが非推奨化

deno vendorコマンドが非推奨化されました。

今後はdeno.json"vendor": trueを指定するか--vendorオプションを使用することが推奨されます。

ForeignFunction.callbackの削除

ForeignFunction.callbackがFFIなどの改善により不要になったため、削除されています。

Web API

Blob#bytes

新規APIとしてBlob#bytesが実装されています。

バグ修正

deno check

型チェックが必要無い際はcompilerOptions.typesで指定された型定義がダウンロードされないように挙動が改善されています。

deno task

カレントディレクトリなどの変更の操作がsubshellの外部にも伝播してしまう問題が修正されています。

Windows

Denoがホームディレクトリを探索する際にUSERPROFILE環境変数が参照されるように挙動が変更されているようです。

WebGPU

TypeScriptの型定義においてGPUUncapturedErrorEventEventではなくEventTargetのサブクラスとして定義されていた問題が修正されています。

参考