虎の穴開発室ブログ

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

MENU

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

皆さんこんにちは。 最近は、ドンオニタイジン に見守られて仕事しています。 おっくんです。

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

Deno 1.23

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

型チェックのデフォルト動作が変更されました

Deno 1.22 の時点で、一部適用になった型チェックのデフォルトの動作変更が、計画通りこのリリースで適用されました。

deno run hoge.ts では、型チェックがされなくなっています。 型チェックをする場合には、deno check hoge.ts のようにして主体的な実行が必要です。

unstable な API Deno.sleepSync が削除されます

このリリースで Deno.sleepSync が削除されます。 Deno.sleepSync はイベントループを完全にブロックするスリープ機能のため、問題を起こす可能性があると判断されたためです。 例えば、Web サーバーアプリケーション内で使用すると、その間にリクエストの一切を受け入れられなくなるなどの問題が想定されています。

これらを理解の上で、もしイベントループの一切のブロックが行われるスリープを行いたい場合には、以下実装で機能を代替することができると紹介されています。

function sleepSync(timeout) {
  const sab = new SharedArrayBuffer(1024);
  const int32 = new Int32Array(sab);
  Atomics.wait(int32, 0, 0, timeout);
}

CLI ツールを作成していたりという場面では、お世話になるケースが有るかもしれません。

動的インポートされたファイルも監視できるようになります

このリリースから、--watch オプションを使用したファイル監視の際、動的インポートされたファイルも監視対象になります。

// 今までも --watch で監視できていた
import foo from "./foo.ts"

// 動的インポートは、このリリースから監視できるようになった
const bar = await import("./bar.ts");

deno task が機能追加

このリリースで deno task にいくつかの機能追加が行われています。

--cwd フラグを追加

deno task に定義されたシェルの中には、現在のディレクトリに依存するものがあるかもしれません。

これまでは、「現在のディレクトリ」に依存していましたが、このリリースから実行時の基準となるディレクトリのパスを設定することができます。

次のような deno task の定義を deno.jsonc を作成して用意して確認します。

# deno task の定義を確認
$ cat deno.jsonc
{
    "tasks":{
        "task1": "deno run output_log.ts >> log/log.log",
    }
}

# output_log.ts が . と./srcに設置されています。
$ tree
.
|-- deno.jsonc
|-- log
|-- output_log.ts
`-- d1
    |-- log
    `-- output_log.ts

1 directory, 4 files

# 比較のため、2つのoutput_log.ts は出力内容を変えています。
$ cat output_log.ts
console.log("Output log 1.")

$ cat d1/output_log.ts
console.log("Output log 2.")

# --cwd を使わない場合、deno.jsonc(または.json) を置いたディレクトリを作業ディレクトリにします
$ deno task task1
Task task1 deno run output_log.ts >> log/log.log

$ cat log/log.log
Output log 1.

# --cwd を使うことで作業ディレクトリを指定できます
$ deno task --cwd d1 task1
Task task1 deno run output_log.ts >> log/log.log

$ cat log/log.log
Output log 1.

# 作業ディレクトリがd1 になったので、ログの書き出しは d1/log/log.log になる
$ cat d1/log/log.log
Output log 2.

上位ディレクトリに deno.jsonc があり、子ディレクトリでパラメータを変えた複数のサーバーアプリがあり、どれも server.ts をエントリポイントにしている場合など、コマンドを集約できるので、便利に使用できる場面がありそうです。

リダイレクトをサポート

このリリースで deno tasks の標準出力と標準エラー出力をファイルへリダイレクトするサポートが追加されています。

以下のように記述することで、標準出力を log/log.log へリダイレクトしています。

[deno.jsonc]

{
  "tasks": {
    "task1": "deno run output_log.ts >> log/log.log"
  }
}

次のように、output_log.ts が実装されてるとします。

[output_log.ts]

console.log("Output log 1.")
console.error("Output Error 1.")

実行すると、次のようになります。

$  deno task task1
Task task1 deno run output_log.ts >> log/log.log
Output Error 1. # <= リダイレクトしたはずがコンソールに出てきてしまった

上記のように、コンソールに、console.error("Output Error 1.") の出力結果が出てきてしまいました。

これは、console.error("Output Error 1.") は標準エラー出力に出てきているものだからです。

標準エラー出力または、両方をリダイレクトする場合には次のようにします。

[deno.jsonc(修正)]

{
  "tasks": {
    // 標準出力をリダイレクト
    "task1": "deno run output_log.ts >> log/log.log",
    // 標準エラー出力をリダイレクト
    "task2": "deno run output_log.ts 2>> log/log.log",
    // 標準出力、標準エラー出力をリダイレクト
    "task3": "deno run output_log.ts &>> log/log.log"
  }
}

実行すると次のようになります。

# 標準出力をリダイレクト
$ deno task task1
Task task1 deno run output_log.ts >> log/log.log
Output Error 1.

$ cat log/log.log
Output log 1.

# 標準エラー出力をリダイレクト
$ deno task task2
Task task2 deno run output_log.ts 2>> log/log.log
Output log 1.

$ cat log/log.log
Output log 1.
Output Error 1.

# 標準出力、標準エラー出力をリダイレクト
$ deno task task3
Task task3 deno run output_log.ts &>> log/log.log

$ cat log/log.log
Output log 1.
Output Error 1.
Output log 1.
Output Error 1.

複数のリダイレクト先の設定は実装されていないのが注意事項だそうです。

クラスプラットフォームの cat と xargs の追加

deno task には、cp や mv といったいくつかの組み込みクラスプラットフォームコマンドが用意されています。

Deno Manual - Task runner - Built-in commands

これらに cat と xargs コマンドが追加になりました。

deno fmt が更新されまさした

deno fmt が更新され、.cjs .cts .mjs .mts をサポートするようになりました。

また、型定義に不要な()が削除されるようになりました。 以下の内容で記述されたコードを用意します。

type Test = (string | number);

以下のソースをにフォーマットを掛けます。 すると以下のようになります。

type Test = string | number;

意味の有るコードではないですが、以下のような型定義であった場合には、フォーマット後も変化はありませんでした。

type Test = (string | number) | null;

新しい unstable な API Deno.getGid() が追加されます

Deno.getGid() を使用することで、実行ユーザーのグループを取得することができます。 確認してみます。

$ whoami
root

$ grep root /etc/group
root:x:0:

$ cat get_gid.ts
console.log(Deno.getGid());

$ deno run --allow-env --unstable get_gid.ts
0

上記のように、グループを取得できました。 こちらは macOS, Linux 向け機能となっており、Windows 環境では null を返します。

REPL が改行に対応しました

REPL が便利になります。 ctrl + s で、改行できるようになります。 REPL なのに「複数行まとめて書いて、実行」ということができるようになりました。

FFI API が更新されました

これまで、FFI を介して JavaScript 側に 64bitの値を返されたとき、JavaScriptのnumberに基づく値が返されていました。 このことにより、64bitの値が53bitになることで、誤った結果を受け取ることがありました。 このリリースから、BigIntで値が返されるようになるとともに、パラメータとしてBigIntを渡すことができるようになります。

CompressionStream と DecompressionStream が、deflate-raw サポート

Denoは、新しく RFC1951 の DEFLATE algorithmdeflate-raw フォーマットをサポートするようになりました。 リリースノートを参考に以下を用意します。

[compress.ts]

let input = await Deno.open("text.txt");
const compressed = input.readable.pipeThrough(
  new CompressionStream("deflate-raw"),
);
let output = await Deno.open("text.txt.zz", { create: true, write: true });
compressed.pipeTo(output.writable);

こちらを動かすと次のようになります。

# 圧縮を実行
$ deno run -A compress.ts

# 結果確認(一部抜粋) 
$ ls -la
-rwxrwxrwx 1 root root  242 Jun 19 17:15 compress.ts
-rwxrwxrwx 1 root root  437 Jun 19 17:08 text.txt
-rw-r--r-- 1 root root   40 Jun 19 17:15 text.txt.zz

かなり容量が小さくなっているのが分かります。 解凍をする実装は次の通りです。

[decompress.ts]

let input = await Deno.open("text.txt.zz");
const decompressed = input.readable.pipeThrough(
  new DecompressionStream("deflate-raw"),
);

let output = await Deno.open("decompress.text.txt", { create: true, write: true });
decompressed.pipeTo(output.writable);
$  deno run -A decompress.ts

$ ls -la
-rwxrwxrwx 1 root root  242 Jun 19 17:15 compress.ts
-rw-r--r-- 1 root root  437 Jun 19 17:20 decompress.text.txt
-rwxrwxrwx 1 root root  260 Jun 19 17:20 decompress.ts
-rwxrwxrwx 1 root root  437 Jun 19 17:08 text.txt
-rw-r--r-- 1 root root   40 Jun 19 17:15 text.txt.zz

解凍結果の decompress.text.txttext.txt 容量は一致します。

RFC1951 の deflate-row は、どこで使用されるのかというところで調査したら Chromium Blogに記載を見つけました。

Chromium Blog - Chrome 103 Beta: Early Navigation Hints, a Host of Completed Origin Trials, and More

Chromium でも deflate-row をサポートするという趣旨で記述があります。

その他

  • deno info--config --no-config フラグをサポート
  • deno に同梱される TypeScript が 4.7 に更新されました
  • Windows 向けに SIGINT SIGBREAK を リッスンできるようになりました
  • deno.land/std モジュール群の変更

まとめ

このリリースでは、REPL が改行できるようになったり、クラスプラットフォームの cat と xargs の追加になったりなど、「便利」な点が目立っていたように思います。

Deno 2 の登場が、2022年の前半に予定しているという発表が今年のはじめに出ていたのですが、Deno のGithubを見ると 1.25 1.26 のマイルストーンが立ち上がっていました。 Deno 2 の登場はもうしばらく先になるようです。

2022 年 7 月 21 日に Deno1.24 も公開されたので、こちらもまた追いかけていきます。

P.S.

採用情報

■募集職種
yumenosora.co.jp