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

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

Node.js互換性の改善

.npmrcのサポート

プライベートレジストリからnpmパッケージを読み込むために、.npmrcのサポートが追加されています。

現時点ではpackage.jsonまたはdeno.jsonと同一ディレクトリにある.npmrcのみが探索されます (ホームディレクトリなどからの読みこみはまだサポートされていません)

.npmrcの設定内容はnpm:などによりnpmパッケージを利用する場合に適用されます。設定内容としては、現時点では_authToken_authのみがサポートされています。

組み込みパッケージ

主にgrpc-nodeやNext.js, Eleventyなどに関連したNode.js組み込みパッケージの互換性が改善されています。

Next.jsのサポートについて

公式ブログによると、DENO_FUTURE=1の指定が必要なもののNext.jsが動作するようになったようです (後日ブログポストが公開予定とのこと)

@google-cloud/visionのサポート

@google-cloud/visionも動作するようになったようです。

主な変更点

  • node:buffer: isUtf8isAsciiが実装されています
  • node:fs: fstatSyncthrowIfNoEntryオプションがサポートされています
  • node:fs: writeなどでposition引数がうまく機能しない問題が修正されています
  • node:http: ServerResponsestatusCodeのデフォルト値がundefinedから200に変更されています

node_modules/.bin

Denoがnode_modulesを作成する際に、node_modules/.binが作成されるようになりました。

$ deno run --allow-env --allow-read --node-modules-dir npm:cowsay@1.6.0 hi

$ ls node_modules/.bin
cowsay  cowthink

deno.lockサポート

今までdeno.lockdeno.jsonがある場合は自動的に生成されていました。今回のリリースでpackage.jsonがある場合にも自動でdeno.lockが作成されるように挙動が変更されました。

またDENO_FUTURE=1が設定された状態でdeno installを実行した際に、deno.lockをベースにパッケージを解決することによりパフォーマンスの改善も図られています (#23918)

deno task

deno taskでスクリプトを実行する際に、そのスクリプトでnpm runが利用されていて かつ npm runにフラグが指定されていなければ、npm rundeno taskに置きかえた上でpackage.jsonのスクリプトが実行されるように挙動が変更されています。

例えば、以下のような内容のdeno.jsonpackage.jsonが存在する場合、deno task testを実行すると、package.jsonhiスクリプトが実行されます。

deno.json:

{
  "tasks": {
    "hi": "echo deno.json",
    "test": "npm run hi"
  }
}

package.json:

{
  "scripts": {
    "hi": "echo package.json"
  }
}

Deno API

Deno.exitCode

Deno.exitCodeが追加されました。process.exitCodeと同様に、プロセス終了時の終了コードを設定することができます。

$ deno eval 'Deno.exitCode = 1;’
$ echo $?
1

FFI (Deno.dlopen)

i64u64型がnumber | bigint型からbigint型で取り扱われるように変更されています。

安定化

Deno.FsFile

Deno.FsFileの下記メソッドが安定化されました。(--unstable-fsなしで利用できます)

  • sync
  • syncSync
  • syncData
  • syncDataSync
  • lock
  • lockSync
  • unlock
  • unlockSync

DENO_FUTURE=1

DENO_FUTURE=1が設定された場合、下記の機能を--unstable-*オプションなしで利用できるようになりました。

  • FFI (Deno.dlopenなど)
  • WebGPU API
  • unstableなファイルシステムAPI (Deno.umaskなど)

Deno.upgradeWebSocketidleTimeoutのデフォルト値の変更

Deno.upgradeWebSocketidleTimeoutオプションのデフォルト値が120から30に変更されています。Nginxなどはデフォルトで60秒を想定しており、その影響で120秒だと想定よりも早くDeno.upgradeWebSocketでWebSocket接続が切れてしまう問題があったようです。

Web API

Request#bytes()/Response#bytes()

RequestResponsebytesメソッドがサポートされました。リクエストまたはレスポンスのボディをUint8Arrayとして取得できます

const response = new Response("OK");
const body = await response.bytes();
console.assert(body instanceof Uint8Array);
console.assert(new TextDecoder().decode(body) === "OK");

ReadableStream.fromの改善

ReadableStream.fromIterableIteratorだけでなくIterableもサポートされました。

const readable = ReadableStream.from({
  [Symbol.iterator]() {
    let done = false;
    return {
      next() {
        if (done) {
          return { done: true };
        } else {
          done = true;
          return { value: 123, done: false };
        }
      },
    };
  },
});
console.info(await Array.fromAsync(readable)); // => [ 123 ]

また、ReadableStream.fromSymbol.asyncIterator/Symbol.iteratorの取り扱いが改善されています。これらにnullが設定されていた場合に、undefinedが指定された場合と同様に振る舞うように挙動が変更されています。

CLI

deno test

時間がかかっているテストケースへの警告

deno testでテストケースの実行に時間がかかっている場合に警告が表示される機能が追加されました。

デフォルトではDENO_SLOW_TEST_TIMEOUT*(2**n)ごとの間隔で警告が表示されます (DENO_SLOW_TEST_TIMEOUTのデフォルト値は60のため、60秒 → 120秒 → 240秒…といった間隔で警告が表示されます)

$ DENO_SLOW_TEST_TIMEOUT=5 deno test test.js
running 1 test from ./test.js
slowTestCase ...'slowTestCase' has been running for over (5s)
'slowTestCase' has been running for over (10s)
'slowTestCase' has been running for over (20s)

--cleanオプションが追加

deno testコマンドに--cleanオプションが追加されています。--coverageオプションとの併用が想定されていて、このオプションが指定されている場合はテストの実行前にcoverageディレクトリが削除されます。

deno coverage

deno coverageコマンドで--ignoreオプションが動作しない問題が修正されています。また、coverageディレクトリにリモートスクリプト(https:)に対するjsonファイルが生成されてしまう問題も解消されています。

deno lint

no-boolean-literal-for-argumentsルールの追加

no-boolean-literal-for-argumentsルールが実装されています。以下のようにbooleanリテラルを関数の引数として指定している箇所に対して警告されます。

function renderReport(verbose: boolean) {
  // ...
}
renderReport(true); // => エラー
renderReport(false); // => エラー

以下のように定数を利用することで警告を解消できます。

const VERBOSE = true;
const CONCISE = false;
function renderReport(verbose: boolean) {
  // ...
}
renderReport(VERBOSE);
renderReport(CONCISE);

このルールはデフォルトでは無効化されているため、利用する際はdeno.jsonなどで明示的に有効化する必要があります。

{
  "lint": {
    "rules": {
      "include": ["no-boolean-literal-for-arguments"]
    }
  }
}

no-unused-varsルールの改善

no-unused-varsルールがJSX/TSXファイルでも動作するように改善されています。

deno serve

deno serveコマンドの--portオプションに0を指定した場合、ランダムな空きポートが採番されるように改善されました。

vendor

vendorディレクトリ(deno.json"vendor": trueを指定すると作成されます)のリモートファイルを編集しても、deno.lockによる検証でエラーが発生しないように挙動が改善されています。

deno -v

deno -vでバージョンを表示できます。

$ deno -v
deno 1.44.0

パフォーマンス改善

メモリ消費の改善

v8のPointer Compressionを有効化することで、メモリ使用量の最適化が図られています。

キャッシュ用のSQLiteデータベースでWALモードが有効化

DENO_DIR配下に作成される各種キャッシュ用のSQLiteデータベースでjournal_mode=WALが適用されるようになりました。(v8コードキャッシュやdeno lint, tscによる型チェックの高速化などで活用されています)

これにより起動の高速化などが期待されるようです。この変更の影響でデータベースのファイル名がv2に変更されています (例: $DENO_DIR/v8_code_cache_v2)

node_modules

node_modulesのセットアップに関するパフォーマンスが改善されています。特にmacOSではcopyfileの代わりにclonefileを使うようにする最適化が導入されており、大幅な改善が見込まれるようです。(#23980)

処理の並列化

swcによるソースの解析などを並列化することで、スクリプトの起動の高速化が図られています。

バグ修正

Deno.writeFileReadableStreamを渡すと、元のファイルの内容が部分的に置き換えられてしまう問題が修正されています。

参考