虎の穴開発室ブログ

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

MENU

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

皆さんこんにちは。少しずつ暖かくなって来るこの時期、そろそろ花粉症が怖い おっくん です。

去る 2020 年 1 月 20 日に Deno1.7 がリリースされました。
今回も、リリース内容の中から気になったものをピックアップして、紹介したいと思います。

実行環境

  • macOS Catalina 10.15.7
  • Windows 10 20H2 19042.685

アップデートのやり方

今回は Deno 1.6.0 から Deno 1.7.0 へのアップデートを行います。

アップデートする Deno 1.1.0 を導入した時のコマンドは以下の通りです。

curl -fsSL https://deno.land/x/install/install.sh | sh

アップデートは、以下のコマンドで実施しました。

$ deno upgrade
# バージョン指定する場合は次のコマンドで実行します。
# deno upgrade --version 1.7.0

ネットワーク環境もあるでしょうが、完了するまでに 3 分程度かかりました。

方法については、こちらに記載がありました。 Deno Manual

deno.land

Deno 1.7

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

deno.land

deno compile が改善されました

「deno compile」は、スタンドアロンな実行バイナリを作成する機能ですが、こちらに 3 点の改善がされました。

改善された機能は、3 つです。

  • 実行時に--lite を付与することにより Deno 1.6 で compile を実行した時と比べ、40%から 60%程度容量が削減されるようになりました。
  • Windows x64 と macOS x64 そして Linux x64 のいずれかアーキテクチャから、他のアーキテクチャにクロスコンパイルできるようになりました。
  • --allow-net といった実行時引数を付与したバイナリが作成できるようになりました。

順を追って試します。

Dene 1.6 と比べ、40%から 60%程度コンパイル結果の容量が削減されるようになった

以前の deno compile は、コンパイル結果にDeno本体を含むためにコンパイル結果はDeno本体よりも容量が大きくなっていました。
こちらについて、以前の記事で Deno1.6 を使用したコンパイル結果の容量比較を行っています。

toranoana-lab.hatenablog.com

-- lite を実行時に付与することで、容量の削減ができるようになったとのことなので、試します。
比較には Deno 1.6 でのコンパイル結果の容量比較にも使用した、以下の sample1.ts を使用します。

[sample1.ts]

import { serve } from "https://deno.land/std@0.62.0/http/server.ts";

for await (const req of serve({ port: 8000 })) {
  req.respond({ body: "Hello World" });
}

上記の sample1.ts を Deno1.7 でコンパイルした結果も並べると以下のようになります。

ファイルサイズ(byte)
Deno1.6 本体 48,779,678
Deno1.6で作成されたバイナリ 48,823,062
Deno1.7 本体 52,843,056
Deno1.7 で作成されたバイナリ 52,887,063
Deno1.7で --lite を付与して作成されたバイナリ 31,129,087

確かに、--lite を付与することで、約40%程度容量削減できました。

また、並べてみて気が付いたことですが、Deno 1.7 本体の容量は、 Deno 1.6 と比べて、数%大きくなっていました。

Windows x64 と MacOS x64 そして Linux x64 向けにクロスコンパイルできるようになった

アーキテクチャを跨いだクロスコンパイルができるということですので、
今回は実行環境 MacOS x64 、コンパイルターゲットをWindows x64 の組み合わせで試してみます。

リリースノートに詳細の記載はないのでDeno Manual の Compiling Executablesを参照しながら進めます。

deno.land

--target で指定可能なコンパイルターゲットは deno compile --helpを参照することが記載されています。

deno compile --helpを実行した結果から、--targetで示されている取りうる設定は以下の4択でした。

  • x86_64-unknown-linux-gnu
  • x86_64-pc-windows-msvc
  • x86_64-apple-darwin
  • aarch64-apple-darwin

この中から、x86_64-pc-windows-msvc を使用し、sample1.ts を windows向けにクロスコンパイルを次のコマンドを試しましたが、エラーになってしまいました。

deno compile --unstable --allow-net --lite --target x86_64-pc-windows-msvc sample1.ts --output sample1.exe
# - 出力結果 - 省略 -
thread 'main' panicked at 'assertion failed: exe_path.exists()', cli/tools/upgrade.rs:231:3note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

調べてみると次のissueが上がっていました。

compile panic on cross compilation (from Linux)

github.com

要するに、オプションを与える順番が大事になるとのことですので、並び替えて以下を実行します。

deno compile --unstable --output sample1.exe sample1.ts --allow-net --target x86_64-pc-windows-msvc --lite

コンパイルをエラーなく実行できたので、Windows環境で実行してみましたが、エラーを表示し実行できませんでした。

f:id:toranoana-lab:20210204103859p:plain

残念ですが、クロスコンパイルの調査は今回はここまでとします。
前提とした条件などの不足があるかもしれませんので、こちらは継続して調査を進めたいと思います。

実行時引数を付与したバイナリが作れるようになった

先に示しているようにsample1.tsは、Hello Worldの文字列を返してくるだけのサーバーです。
コンパイルには、以下のようにネットワークの利用を許可する--allow-netの付与が必要です。

deno compile --unstable sample1.ts --allow-net
./sample1
# => 0.0.0.0:8000でサーバーとして動作

--allow-netを付与しないでコンパイルすると以下のようにエラーになります。

deno compile --unstable sample1.ts
./sample1
# 以下のエラーを表示します。
error: PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
    at processResponse (deno:core/core.js:212:11)
    at Object.jsonOpSync (deno:core/core.js:235:12)
    at opListen (deno:runtime/js/30_net.js:17:17)
    at Object.listen (deno:runtime/js/30_net.js:183:17)
    at Object.listen (deno:runtime/js/40_net_unstable.js:11:18)
    at serve (file://$deno$/bundle.js:1427:28)
    at file://$deno$/bundle.js:1438:25

compile コマンド自体の機能は拡充しましたが、現在も実行時には --unstable の付与が必要な実験的な機能となっています。 クロスコンパイルを試してみた結果からすると、納得できる状況だと感じます。

deno fmt がマークダウンをサポートするようになりました

deno fmtは、deno付属のフォーマッタです。
こちらがマークダウンをサポートするようになりました。

次のtest.mdをフォーマットしてみます。

[test.md(フォーマット前)]

# タイトル
## 最近の出来事
- 1つ目 
内容
- 2つ目 
内容
- 3つ目 
内容

以下のコマンドでフォーマット実行できます。

deno fmt test.md

フォーマット結果は以下の通りです。

[test.md(フォーマット後)]

# タイトル
 
## 最近の出来事
 
- 1つ目
  内容
- 2つ目
  内容
- 3つ目
  内容

改行・インデントの追加が違和感なく行われます。

また、コードのフォーマットをする際の拡張子を指定できるようになりました。
リリースノートでも示されているように、ディスク上のファイルをフォーマットするときには動作しないので、catの出力結果をフォーマットしてリダイレクトします。

cat sample1.ts | deno fmt --ext=ts - > dist.ts

動作を試しましたが、妙なところで改行したりとお勧めできないかなと思います。

[上記コマンドのフォーマット結果 dist.ts 抜粋]

for await (const req of serve({ port: 8000 })) { req.respond({ body: "Hello
World!!!" }); }

データURLのインポートのサポート

データURLは、ダイナミックに生成されたコードの実行をするにあたり便利な機能です。
ソースのエンコード結果をインポートしてデータを読み込むことができます。

試してみます。

data.tsを作成します。

[data.ts]

export const data = "Export Data!!"
 
export const func = ()=>{
 console.log("Export Func!!")  
}

こちらをbase64エンコードします。

cat data.ts | base64
# => ZXhwb3J0IGNvbnN0IGRhdGEgPSAiRXhwb3J0IERhdGEhISIKCmV4cG9ydCBjb25zdCBmdW5jID0gKCk9PnsKICBjb25zb2xlLmxvZygiRXhwb3J0IEZ1bmMhISIpICAgCn0=

import.tsでエンコード結果を読み込ませます。

[import.ts]

import * as data from "data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGRhdGEgPSAiRXhwb3J0IERhdGEhISIKCmV4cG9ydCBjb25zdCBmdW5jID0gKCk9PnsKICBjb25zb2xlLmxvZygiRXhwb3J0IEZ1bmMhISIpICAgCn0="
 
console.log(data.data)
data.func()
// => Export Data!!
// => Export Func!!

APIでデータを受け取るのと比べて何が有利なのか?と考えましたがパラメータだけでないロジックまでダイナミックに変更した関数も渡せるという点が有利な部分と感じました。
ただ、このレベルでダイナミックな変更をするケースを、業務に即したレベルで具体的なケースとしては少々考えにくいものでした。

新しいAPI Deno.resolveDns

denoからDNSの問い合わせができるAPIが追加されました。
リリースノートを参考にこのブログのドメインのAレコードの情報を参照してみます。

[sample2.ts]

const records = await Deno.resolveDns("toranoana-lab.hatenablog.com", "A");
for (const ip of records) {
 console.log(ip);
}

実行時のコマンドで実行します。

deno run --allow-net --unstable sample2.ts
# => 13.230.115.161
# => 13.115.18.61

DNS問い合わせが Denoの単体でできました。
現在サポートされていないプロトコルとして、DNS over HTTPS や DNS over TLS が挙げられています。
Denoの機能だけで、Whois 情報を提供する簡単なサイトなら作成できるかもしれません。

DenoAPI の変更

いくつかのメソッドに変更がありますが、Deno.createHttpClientへの変更が代表的なものです。

// Old
- Deno.createHttpClient({ caFile: "./my_ca.pem" });

// New
+ Deno.createHttpClient({ caData: Deno.readFileSync("./my_ca.pem") });

APIで証明書を指定する caFile のプロパティが削除され、読んだものをcaData プロパティに渡す方式に変わっています。
Deno 1.4 でreadJsonAPI が廃止されたのと同じ思想を感じます。

こんなissueがありました。
Remove caFile from Deno.createHttpClient options

github.com

決定経緯にかかわるものは見つけられませんでした。

そのほか

  • Web Worker での アクセス許可のサポート
    親プロセスで許可したアクセス許可の内容をWeb Workerが引き継ぎます。
  • globalThis.location のサポート
  • fetch のリクエストボディストリーミングをサポート

など。


Deno 1.7 の追加機能・変更事項を見てきました。
前回の記事で deno compile 結果の容量削減について issue が出ていることを紹介しましたが、既に取り込まれています。 クロスコンパイル結果を動作確認することは今回失敗しましたが、継続して調査をしたいと思います。

P.S.

直近のイベント情報

■2/12(金)19:30~ とらのあなラボエンジニア座談会Vol.6【〜オタク向けプラットフォームを作ってみた〜】
yumenosora.connpass.com

■2/19(金)19:30~ とらのあなWebデザイナー・UIデザイナー採用説明会 yumenosora.connpass.com

採用情報

■募集職種
yumenosora.co.jp

カジュアル面談も随時開催中です

■お申し込みはこちら!
yumenosora.connpass.com

■ToraLab.fmスタートしました!

メンバーによるPodcastを配信中!
是非スキマ時間に聞いて頂けると嬉しいです。
anchor.fm

■Twitterもフォローしてくださいね!

ツイッターでも随時情報発信をしています
twitter.com