虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

Deno 1.34 へのアップデートと変更事項まとめ

皆さんこんにちは。おっくんです。

去る 2023 年 5 月 25 日に Deno 1.34 がリリースされました。 今回も、リリースノートを参考に 変更事項の気になるところを紹介します。

Deno 1.34

Deno 1.34 での変更事項をDeno 1.34 リリースノートを元に確認します。

deno compile が npm パッケージに対応しました

Deno 1.6 で登場した単一実行バイナリを作成する deno compile が登場しました。
Deno 1.32 では、Web ワーカーと動的インポートに対応しており、こちらに続いての機能拡張として、npm パッケージに対応しました。

リリースノート記事を参考に Deno 1.33 と Deno 1.34 で動作の比較をすると次の様になります。

$ cat main.ts
import { say } from "npm:cowsay@1.5.0";
console.log(say({ text: "Hello from Deno!" }));

$ deno -V
deno 1.33.0

$ deno compile --allow-read main.ts
Check file:///usr/src/app/main.ts
error: npm specifiers have not yet been implemented for this sub command (https://github.com/denoland/deno/issues/15960). Found: npm:cowsay@1.5.0
# npm: に対応していないことが明確にエラーとして出てくる

$ deno -V
deno 1.34.0

$ deno compile --allow-read -o compiled_main main.ts
Check file:///usr/src/app/main.ts
Compile file:///usr/src/app/main.ts compiled_main

$ ./compiled_main
 __________________
< Hello from Deno! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Deno 1.34 では、npm: を使用したnpmモジュールも deno compile できていることがわかります。
リリースノート記事では、vite や eslint の動作も紹介されています。 Deno 開発チームのテストでは、非コンパイルなローカルにキャッシュされた依存関係を使うよりも deno compile を使った方が起動時間が早い傾向も見られるそうです。

頻繁に起動を繰り返す場合や単純に起動時間に厳しい制約がある場合には、使用を検討しても良いのではないでしょうか?

Deno 1.7 ではそれ以前より、deno compile の結果がそれ以前より40~60%程度小さくなるようになるアップデートが入っていましたが、バイナリサイズを最小限に抑えるなどの改善がまだ残っているそうです。

改善内容について Q1 Roadmap に記載がないか見てみましたが 具体的に該当する部分は見受けられませんでした。

deno.json と CLI での glob 構文をサポート

glob が、deno.json deno task そして CLI でサポートされるようになりました。 導入された glob 構文は、Windows macOS Linux でクロスプラットフォームで動作します。

実際に使ってみると次の様に動作します。

$ ls -la
total 5
drwxrwxrwx 1 root root    0 May 28 09:15 .
drwxrwxrwx 1 root root 4096 May 27 17:00 ..
-rwxr-xr-x 1 root root   88 May 27 17:43 main.ts

$ deno -V
deno 1.33.0

$  deno fmt -- --include="./m*.ts"
error: No target files found.
# Deno 1.33 では未対応なので、ファイルを見つけられない

$ deno -V
deno 1.34.0

$ deno fmt -- --include="./m*.ts"
Checked 1 file

deno.json 設定ファイルの改善

すべてのサブコマンドから、ファイルとフォルダを除外する

Deno fmt などサブコマンド対象外になるように設定するには、個別の設定が必要でした。 そのため、すべてのサブコマンドから除外したい場合には、すべて個別の設定でしたが、このリリースでトップレベルの exclude プロパティを使用できるようになりました。

リリースノート記事を元に確認すると次の様になります。

$ ls -la
total 6
drwxrwxrwx 1 root root    0 May 28 09:47 .
drwxrwxrwx 1 root root 4096 May 27 17:00 ..
-rwxr-xr-x 1 root root  187 May 28 09:48 deno.json
-rwxr-xr-x 1 root root   90 May 28 09:46 main.ts
-rwxr-xr-x 1 root root   20 May 28 09:48 sub.ts

$ cat deno.json
{
  "fmt": {
    "exclude": ["./main.ts"]
  },
  "lint": {
    "exclude": ["./main.ts"]
  },
  "test": {
    "exclude": ["./main.ts"]
  },
  "bench": {
    "exclude": ["./main.ts"]
  }
}

$ deno fmt
/usr/src/app/1_34/deno.json
/usr/src/app/1_34/sub.ts
Checked 2 files

# ここで、deno.json を書き換え

$ cat deno.json
{
  "exclude": ["main.ts"]
}

$ deno fmt
Checked 2 files

シンプルに記述できるのが非常にイイですね。

LSP サーバーの改善

Deno 1.33 で、ドキュメントのプリロードが導入されました。 この機能のプリロード件数が、カスタマイズできるようになりました。 deno.documentPreloadLimit プロパティを設定することで、カスタマイズできます。

また、このリリースでヒープサイズも3GBまで拡張できるようになりました。

Deno.API の変更

Deno.serve() の仕様変更

Deno 1.33 リリースのタイミングでは、来月に Deno.serve() の安定化が予定されていましたが、こちらが1カ月延期になりました。 理由は、APIの上位互換性の向上です。

Deno.serve() は、Promise<void> ではなく Deno.Server を返すようになりました。 Deno.Server には、finished プロパティがあり、(AbortSignalを使った)サーバーの停止によって解決します。

Deno 1.33 と比較して確認します。

$ deno repl --unstable
Deno 1.33.0
exit using ctrl+d, ctrl+c, or close()
> const server = Deno.serve((_req) => new Response("Hello world"))
✅ Granted net access to "0.0.0.0:8000".
Listening on http://localhost:8000/
undefined
> console.log(server)
Promise { <pending> }
undefined
> console.log(Deno.inspect(server))
Promise { <pending> }
undefined
>

$ deno repl --unstable
Deno 1.34.0
exit using ctrl+d, ctrl+c, or close()
> const server = Deno.serve((_req) => new Response("Hello world"))
✅ Granted net access to "0.0.0.0:8000".
Listening on http://localhost:8000/
undefined
> console.log(server)
{
  finished: Promise { <pending> },
  ref: [Function: ref],
  unref: [Function: unref]
}

Deno 1.34 になり、finished プロパティ, ref, unref メソッドを持ったオブジェクトが返ってきているのがわかります。

続けて、リリースノート記事の記述を参考に、AbortSignal を使ったサーバー停止を試します。

$ cat server.ts
const ac = new AbortController();
const server = Deno.serve(
  { signal: ac.signal },
  (_req) => new Response("Hello world"),
);
setTimeout(() => {
  ac.abort();
}, 1000);
await server.finished;
console.log("Server has shut down");

$ deno run --allow-net --unstable server.ts
Listening on http://localhost:8000/
Server has shut down
# 1秒経ってから停止

Deno.createHttpClient() の追加

unstable な API として、 Deno.createHttpClient() が追加されます。 これは、Fetch API の拡張機能で、より詳細な設定を施した httpClient を作成します。

以下リリースノート記事に記載された使用例を引用します。

const client = Deno.createHttpClient({
  // Set maximum number of idle connections in the connection pool per host to 10.
  poolMaxIdlePerHost: 10,

  // Set a timeout for idle connection being kept alive to 10s. You can disable
  // timeout all together by passing `false`.
  poolIdleTimeout: 10_000,

  // Configure if the client can use HTTP1.
  http1: false,

  // Configure if the client can use HTTP2.
  http2: true,
});

const resp = await fetch("...", { client });

APIドキュメントには、「カスタムTLS証明書を使用したプロキシ接続を可能にする」という趣旨の記述があるので、サンプルの利用法はもちろん、こういった利用も考慮されているようです。

Deno.FileInfo の拡張

Deno.FileInfo に次の新しいフィールドが含まれるようになりました。

  • Deno.FileInfo.isBlockDevice
  • Deno.FileInfo.isCharDevice
  • Deno.FileInfo.isFifo
  • Deno.FileInfo.isSocket

Linux と macOS で動作し、Windowsでは常に null になります。

以下 Deno 1.33 と比較しながら動作確認します。

$ deno
Deno 1.33.0
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.

> const fileInfo = Deno.statSync("main.ts");
undefined

> console.log(fileInfo)
{
  isFile: true,
  isDirectory: false,
  isSymlink: false,
  size: 90,
  mtime: 2023-05-28T09:46:10.216Z,
  atime: 2023-05-28T10:23:00.620Z,
  birthtime: null,
  dev: 150,
  ino: 1688849860324115,
  mode: 33261,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: 4096,
  blocks: 1
}

$ deno
Deno 1.34.0
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.

> const fileInfo = Deno.statSync("main.ts");
undefined

> console.log(fileInfo)
{
  isFile: true,
  isDirectory: false,
  isSymlink: false,
  size: 90,
  mtime: 2023-05-28T09:46:10.216Z,
  atime: 2023-05-28T10:23:00.620Z,
  birthtime: null,
  dev: 150,
  ino: 1688849860324115,
  mode: 33261,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: 4096,
  blocks: 1,
  isBlockDevice: false,
  isCharDevice: false,
  isFifo: false,
  isSocket: false
}
undefined
>

Deno 1.34 では、フィールドが増えているのが確認できます。

その他

  • npm、Node 互換性の改善
    • deno vender が npm: に対応
    • deno task が、package.json ファイルを参照した npm からのスクリプト実行と同様に、プレスクリプトと ポストスクリプトに対応
    • 一部の Node.js API をポリフィル
    • N-API シンボルに対応
  • IP アドレスを含んだTLS証明書を使用できるようになります
  • Deno 1.34 には、V8 11.5、TypeScript 5.0.4 が同梱されます

まとめ

Deno 1.34 のリリースを追いかけてきました。 deno compile の npm 対応は、単一実行ファイルに落とし込みたいケースで使用できるパッケージの総数に大きな差があるという障害が乗り越えられたのが非常に大きいです。 使い方で、パッケージ選定に制約を受けずに済むのはありがたいですね。

すでに Deno 1.38まで がリリースされています。またこちらも追いかけていきます。

採用情報

虎の穴では一緒に働く仲間を募集中です!
この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧下さい。
カジュアル面談やエンジニア向けイベントも随時開催中です。ぜひチェックしてみてください♪
yumenosora.co.jp