皆さんこんにちは。おっくんです。
去る 2022 年 12 月 14 日に Deno 1.29 がリリースされました。 今回も、リリースノートを参考に 変更事項の気になるところを紹介します。
Deno 1.29
Deno 1.29 での変更事項をDeno 1.29 リリースノートを元に確認します。
npm 互換性の改善
カスタムレジストリを環境変数で設定できる
今回のリリースから、環境変数 NPM_CONFIG_REGISTRY
が参照され、カスタム npm レジストリを設定できるようになりました。
現在は、すべての npm パッケージに影響しますが、将来的にはパッケージ毎に異なるレジストリが設定できるようになるそうです。
npm パッケージに対して deno install が使用できるように!
npm:
指定子を使ったnpm パッケージが deno install
に対応しました。
リリースノートでは、cowsay@1.5.0 をインストールしています。
ここでは試しに、シンプルはHTTPサーバーである http-server を deno install し使ってみます。
# http-server が要求するパーミッションを許可します # ここで、許可しない場合実行時に確認されます $ deno install --allow-net=0.0.0.0:8000 --allow-env --allow-read --allow-sys npm:http-server # パッケージ名がそのままコマンドになります $ http-server -p 8000 Starting up http-server, serving ./ # 出力内容を省略 Available on: http://127.0.0.1:8000 http://192.168.16.6:8000 Hit CTRL-C to stop the server
ブラウザでアクセスすると http サーバーが起動していることが確認できます。
REPL の更新
REPL(対話的動作) にいくつかの変更が行われました。
npm をサポート
REPL で npm パッケージを使えるようになりました。
非 npm パッケージの導入同様に import するだけで使用できます。
$ deno Deno 1.29.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. > import chalk from "npm:chalk"; undefined > console.log(chalk.red('Hello Deno!')); Hello Deno! undefined >
deno repl がデフォルトでは、パーミッション無しになりました
これまで、deno repl ではすべてのパーミッションが許可された状態でしたが、このリリースより deno run 同様に確認が行われるようになります。
Deno 1.28 とも比較しながら確認します。
[Deno 1.28 での動作]
# パーミッションの確認が出ません $ deno repl Deno 1.28.0 exit using ctrl+d, ctrl+c, or close() > Deno.networkInterfaces() [ { family: "IPv4", name: "lo", address: "127.0.0.1", netmask: "255.0.0.0", scopeid: null, cidr: "127.0.0.1/8", mac: "00:00:00:00:00:00" }, // 省略 ]
[Deno 1.29 での動作]
# パーミッションの確認が出ます $ deno repl Deno 1.29.0 exit using ctrl+d, ctrl+c, or close() > Deno.networkInterfaces() ✅ Granted sys access to "networkInterfaces". [ { family: "IPv4", name: "lo", address: "127.0.0.1", netmask: "255.0.0.0", scopeid: null, cidr: "127.0.0.1/8", mac: "00:00:00:00:00:00" }, // 省略 ] # --allow-sys を設定することで Deno.networkInterfaces() 実行時には、確認されなくなります $ deno repl --allow-sys Deno 1.29.0 exit using ctrl+d, ctrl+c, or close() > Deno.networkInterfaces() [ { family: "IPv4", name: "lo", address: "127.0.0.1", netmask: "255.0.0.0", scopeid: null, cidr: "127.0.0.1/8", mac: "00:00:00:00:00:00" }, // 省略 ]
この変更は、デフォルトで権限が付与されているというのは、Deno の「デフォルトで安全」であるというポリシーに反する状況であったために発生した変更だそうです。
Deno で対話的動作をするには deno
と deno repl
の2つがありますが、deno
はこれまで通りパーミッションがすべて許可されたものになります。
それを示す表示が入るようになりました。
$ deno Deno 1.29.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.
その他には、次の2つのリリースが有りました。
- 実行ステートメント毎の履歴ファイルの更新が行われるようになったそうです。
- --quiet フラグにより補助出力の抑制が優先されるようになりました。
QOL の向上
deno init
Deno 1.25 で登場した deno init は main.ts、main_test.ts の2つを作成するコマンドでした。
このリリースから、deno.jsonc、main_bench.ts も作成されるようになりました。
また、出力内容も更新されています。
構成ファイルの改善
このリリースから、構成ファイルで次の2つを制御できるようになります。
- deno bench の対象と除外
- ロックファイルの設定と無効化
IDEも、これらのオプションを提案するようになりました。
解決できないトップレベル await の表示が改善しました
トップレベル await を Deno はサポートしていますが、解決できない場合、エラーを出して終了していました。この表示が改善しました。 この機能は、V8 の新しいAPIに由来しているそうです。
Deno 1.28 と挙動を比較してみます。
次のソースを用意します。
[unresolve_promise.ts]
await new Promise((resolve) => {}); console.log("hello Deno!!");
Deno 1.28 と Deno 1.29 でそれぞれ実行してみます。
$ deno -V deno 1.28.0 $ deno run unresolve_promise.ts error: Module evaluation is still pending but there are no pending ops or dynamic imports. This situation is often caused by unresolved promises.
$ deno -V deno 1.29.0 $ deno run unresolve_promise.ts error: Top-level await promise never resolved await new Promise((resolve) => {}); ^ at <anonymous> (file:///usr/src/app/1_29/unresolve_promise.ts:1:1)
Deno 1.28 のメッセージの表示だけであったものから、Deno 1.29 で対象箇所の特定が非常に容易になりました。
deno check のフラグに --all が追加されました
これまでは、次の様に deno check と deno run で、外部モジュールを含む型チェックをするコマンドのオプションが違っていました。
deno run --check=all main.ts
deno check --remote main.ts
このリリースから、deno check も all をオプションとして受け入れ、次の様に使用できます。
deno check --all main.ts
リリースノートでは、以前のコマンドも使用可能ではあるものの、新しいコマンドを推奨しています。
既に、deno check -h
での表示されるオプションの一覧からは、--remote が削除されていました。
敢えて使う必要が無ければ切り替えたほうが良さそうです。
node_modules と.git ディレクトリを無視するように
deno fmt、deno lint の対象として node_modules と .git は無視されるようになりました。 もし対象にしたい場合は、次の様に明示的に設定が必要です。
$ deno fmt node_modules
その他には、次の3つのリリースが有りました。
- 誤った --allow-* フラグの使用への警告が出るようになりました。
- VSCode 向けにインレイヒントがデフォルトで有効になりました
- --inspect-wait フラグの追加
Deno API の変更
安定化
これまで unstable だった以下のAPIが stable になりました。
- Deno.TcpConn.setNoDelay()
- Deno.TcpConn.setKeepAlive()
unstable な API の削除
次の3つのAPIが削除されました。
- Deno.spawn()
- Deno.spawnSync()
- Deno.spawnChild()
これらの機能は Deno 1.28 で登場した Deno.Command が引き継ぎます。
Deno.Command#.spawn() の stdout と stderr はデフォルト値は、inherit になります
Deno 1.29 から Deno.Commnad の.spawn() コマンドの、stdout と stderr オプションのデフォルト値が inherit になりました。
リリースノートを参考に次のコードを用意し、Deno 1.28 と動作を比較します。
[spawn.ts]
await new Deno.Command("deno", { args: ["eval", "console.log(1); console.error(2); throw new Error;"], }).spawn();
$ deno -V deno 1.28.0 $ deno run --unstable --allow-run spown.ts # 何も表示されません
$ deno -V deno 1.29.0 $ deno run --unstable --allow-run spown.ts 1 2 error: Uncaught Error console.log(1); console.error(2); throw new Error; ^ at file:///usr/src/app/1_29/$deno$eval.js:1:41 # stdout と stderr は、Deno の stdout と stderr を継承しているので、Deno.Command で呼び出した結果が標準出力に載ってきます
Deno.Commnad の .output() と .outputSync() のstdout と stderr オプションのデフォルト値は引き続き piped です。
Deno.writeFile と Deno.writeTextFile にファイルを作成するオプション createNew が追加されました
以下の4つのファイルに書くAPIに、「新たにファイルを作成する」 createNew オプションが追加されます。
- Deno.writeFile
- Deno.writeFileSync
- Deno.writeTextFile
- Deno.writeTextFileSync
これまでも、create オプションは有りましたが、こちらは既にファイルが有る場合にエラーになりません。
createNew は既にファイルが有る場合にはエラーになります。
実際に確認すると、次の様になります。
$ cat sample.md Sample $ deno Deno 1.29.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. > await Deno.writeTextFile("sample.md", "update text", { create: true }); undefined # create オプションでは、ファイルが既に有ってもエラーにならない > await Deno.writeTextFile("sample.md", "update text 2", { createNew: true }); Uncaught AlreadyExists: File exists (os error 17), open 'sample.md' at async writeFile (deno:runtime/js/40_write_file.js:39:7) at async <anonymous>:2:1 # create オプションでは、ファイルが既に有るとエラーになる。
その他
- Deno 1.29 には TypeScript 4.9 が導入されます
- std モジュールの変更
まとめ
Deno 1.29 のリリースでは npm モジュールのインストールに対応するようになり、単純に npm との互換性とともに、Node.js を利用した開発への互換性が高まっていると感じます。
現在出ているプルリクで一つ注目しているものがあります。
パーミッション(特に例に出されているのは環境変数へのアクセス)について、まとめて許可できるオプションです。
今回 deno install の紹介で使用した http-server も該当するのですが、ある程度の規模のツールになると要求する環境変数も
多く、気持ちとして理解できるところがあります。
こちらが、Deno 1.30 のマイルストーンに入った後に、1.31 に延期になっていますが、期待しています。
次回のリリースも引き続き追いかけます。
P.S.
採用
虎の穴では一緒に働く仲間を募集中です!
この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧下さい。
yumenosora.co.jp