虎の穴開発室ブログ

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

MENU

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

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

去る 2020 年 3 月 2 日に Deno1.8 がリリースされました。 今回も、リリース内容の中から気になったものをピックアップして、紹介したいと思います。 また新機能がたくさん増えていました。

実行環境

  • macOS Catalina 10.15.7

アップデートのやり方

今回は Deno 1.7.0 から Deno 1.8.3 へのアップデートを行います。 (既に 2021 年 4 月 2 日 に Deno 1.8.3 にアップデートされていました。)

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

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

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

$ deno upgrade

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

# deno upgrade --version 1.8.3

ネットワーク環境もあるでしょうが、完了するまでに 30 秒ほどで終わりました。これまでよりはやや早めでした。

方法については、こちらに記載があります。

deno.land

Deno 1.8

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

deno.com

WebGPUAPI を実験的にサポート

WebGPUAPI を 実験的機能としてサポートするようになります。 実験的機能ですから、実行時には、--unstabl の付与が必要な機能です。

WebGPUAPI は、W3C のコミュニティグループが仕様策定を進められている Web 用に GPU ハードウェアの機能を提供するための API です。

gpuweb.github.io

この API を用いて GPU レンダリングと汎用 GPU コンピューティング機能に Deno が直接アクセスできるようになります。 このことにより、開発者は GPU を用いていくつかの数値アルゴリズムの高度に並列実行できるようになります。 グラフィックやレンダリング、加えて機械学習などのアルゴリズムの実行にも寄与します。

現在利用されているほとんどのニューラルネットワークが Python で定義し GPU で計算するモデルを取っていますが、整えられた実行インフラがあれば JavaScript が数学的アイデアを実装する理想的な言語になると信じています。

Deno で、GPU アクセラレーションを使用し TensorFlow.js を実行できるようにすることを目標にしています。
数週間ないし数カ月以内に達成される見込みです。

リリースノートから意訳しました。

もっと要約すると「Deno を用い GPU アクセラレーション の効く動作環境で TypeScript(および Javascript)で実装した TensorFlow.js を用いたアプリケーションを実行できるようにして、覇権握るぞ!」って感じなんでしょうか。 近日達成する見込みを発表してしまうところが、Deno が会社になったこともあり勢いを感じるリリースノート内容です。

GPU アクセラレーションが効いた環境で、TensorFlow.js が実行できるようになると、 関連して ml5.js なども対応できるようになるかと思うので、期待が大きな内容です。

deno の実行環境が、WebGPU を使用可能であるかを判断するサンプルが公開されているので試してみます。

$ deno run --unstable https://deno.com/v1.8/webgpu_discover.ts

https://deno.com/v1.8/webgpu_discover.ts

// Run with `deno run --unstable https://deno.land/posts/v1.8/webgpu_discover.ts`

// Try to get an adapter from the user agent.
const adapter = await navigator.gpu.requestAdapter();
if (adapter) {
  // Print out some basic details about the adapter.
  console.log(`Found adapter: ${adapter.name}`);
  const features = [...adapter.features.values()];
  console.log(`Supported features: ${features.join(", ")}`);
} else {
  console.error("No adapter found");
}

こちらを実行すると次の結果になりました。(適宜改行してあります。)

$ deno run --unstable https://deno.com/v1.8/webgpu_discover.ts
Found adapter: Intel(R) HD Graphics 615
Supported features: depth-clamping, texture-compression-bc, 
mappable-primary-buffers, sampled-texture-binding-array, 
sampled-texture-array-dynamic-indexing, sampled-texture-array-non-uniform-indexing, 
push-constants, address-mode-clamp-to-border, 
non-fill-polygon-mode, texture-adapter-specific-format-features

実行環境の GPU リソースは GPUAdapters とみなし、上では adapter と表示されています。 GPU の型番が表示され、続けて機能一覧が列挙されています。 とりあえずこの端末では WebGPUAPI を利用することができるようです。

続けて WebGPU を用いた画像出力サンプルを紹介されています。

github.com

リリースノートでは三角形の描画が試されているので、今回は他のサンプルを動作させてみます。

# 実行するmod.tsは実行時にローカルに置いたshader.wgslを参照するため、取得します。
$ curl https://raw.githubusercontent.com/crowlKats/webgpu-examples/main/cube/shader.wgsl > shader.wgsl

$ deno --unstable --allow-write=output.png https://raw.githubusercontent.com/crowlKats/webgpu-examples/main/cube/mod.ts

実行した結果できた output.png が以下の通りです。

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

ソースコードを見てみると、まさしく数値計算のレベルでの実装をしているもので、普段のいわゆる画面を操作するような実装で思い描くようなソースコードとはだいぶ趣が違います。 WebGPUAPI が提供するのは、レンダリングや計算などの操作を実行するための API なので、具体的に「立方体」であるとかを作成する API では無いのが敷居の高いところだと感じます。

ICU サポート

ICU といっても「集中治療室」の方ではありません。 International Components for Unicode の略だそうです。 ICU サポートは Deno リポジトリでの 2 番目に望まれていた機能だそうです。

サンプルにあるもの参考に試してみます。

[deno 1.8.3 の場合]

$ deno
Deno 1.8.3
exit using ctrl+d or close()

> const d = new Date(Date.UTC(2021, 4, 2, 0, 0, 0));
undefined

> d.toLocaleString("ja-JP", {
   weekday: "long",
   year: "numeric",
   month: "long",
   day: "numeric",
});
"2021年4月2日金曜日"

日本語のフォーマットになって変換がされています。 この変更により、ブラウザの API と結果が一致するようになりました。

確認のため、Chrome 89.0.4389.90 で開発者コンソールを用いて確認すると以下のようになります。

[Chrome 89.0.4389.90 の場合]

> const d = new Date(Date.UTC(2021, 4, 2, 0, 0, 0));
undefined

> d.toLocaleString("ja-JP", {
   weekday: "long",
   year: "numeric",
   month: "long",
   day: "numeric",
});
"2021年4月2日金曜日"

一致しています。

deno 1.7.0 では以下のようになります。 だいぶ異なっていました。

[deno 1.7.0 の場合]

> const d = new Date(Date.UTC(2021, 3, 2, 0, 0, 0));

undefined
> d.toLocaleString("ja-JP", {
   weekday: "long",
   year: "numeric",
   month: "long",
   day: "numeric",
});

"Fri Apr 02 2021 09:00:00 GMT+0900 (JST)"

これはブラウザの API と同じ結果が返って来るようになって良かったといえそうです。 Deno リポジトリでの 2 番目に望まれていた機能であったこともうなずける内容です。

inport maps が安定化

import maps は JavaScript の import について制御する方法です。

github.com

import maps を使用しない場合、アクセスするとHelloWorld!!!と返すだけのサーバー実装は、次のようになります。

[import maps を使わない簡単な Web サーバー(app.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: "HelloWorld!!!" });
}

これまでよく見かけた実装かと思います。

今度は、インポート先を定義したimport.jsonを用意します

[import.json]

{
  "imports": {
    "std/server": "https://deno.land/std@0.62.0/http/server.ts"
  }
}

https://deno.land/std@0.62.0/http/server.tsstd/server という名称で定義されたので、アプリケーション側を直します。

[import maps を使った簡単な Web サーバー(app.ts)]

import { serve } from "std/server";

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

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

引数に、--import-map=imports.json を与える
$ deno run --import-map=imports.json --allow-net app.ts

ソースコードを複数のファイルに分割した上で、詳細なバージョン情報を埋め込んだ import をしているとファイルによって別バージョンを読んでしまうミスなどが発生しうるので、まとめて管理できるこの inport maps はとても便利だと感じます。

モジュールを取得するための認証トークンをサポート

普段使うよう Deno のモジュールは、パブリックにインターネット公開されています。 例えば、std@<version番号>/hogehogeといったモジュールです。

deno.land

認証が必要なサーバーからモジュールを取得するときに使う認証トークンを環境変数に設定できる機能が追加になりました。

# @以前の部分がトークンとなり、以下の場合
# deno.landのモジュールを取得する時に使うトークンが、a1b2c3d4e5f6 ということになる
# 単一ドメイン設定
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land
# 複数ドメイン設定
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land;f1e2d3c4b5a6@example.com:8080

設定したトークンをリクエストヘッダーに付与し、リクエストすることで認証を行います。

private な github からモジュールを取得するための方法も示されています。

deno.land

ある組織の業務ドメイン情報を含んだアプリケーション間で共通利用されるモジュールなどは、パブリックに公開をしないでしょうから、こういった認証機能を使って管理・取得するのが主流になるのかもしれませんね。

Deno.permissions API が安定化

ネットワークや環境変数などのリソースにアクセスする機能を Deno から扱う場合、実行時のオプションで --allow-net などを付与して実行していました。 しかし、実行時にアプリケーションが対話的に権限を要求するほうが UX に寄与することがあります。

API としてパーミッションの許可をできるのが Deno.permissions API です。

サンプルにある、コードでは動作しないのを確認したので、修正しました。 以下の通りです。

[permission_api.ts(修正)]

function homedir() {
  try {
    console.log(`Your home dir is: ${Deno.env.get("HOME")}`);
  } catch (err) {
    console.log(`Failed to get the home directory: ${err}`);
  }
}

// Try to get the home directory (this should fail, as no env permission yet).
homedir();

// ものサンプルは const { granted } = await Deno.permissions.request({ name: "env" });
// となっていますが、Deno.permissions.request は、
// 結果として、{state: "granted" or "denied" , onchange: null}
// を返すため、元のままだと granted プロパティはないのでエラーとなります。
const { state } = await Deno.permissions.request({ name: "env" });
if (state === "granted") {
  console.log(`You have granted the "env" permission.`);
} else {
  console.log(`You have not granted the "env" permission.`);
}

// Try to get the home directory (this should succeed if the user granted
// permissions above).
homedir();

await Deno.permissions.revoke({ name: "env" });

// Try to get the home directory (this should fail, as the permission was
// revoked).
homedir();
$ deno run permission_api.ts
# 環境変数へのアクセス権の付与前はエラー
Failed to get the home directory: PermissionDenied: Requires env access, run again with the --allow-env flag
# 環境変数へのアクセス許可を要求
⚠️  ️Deno requests access to environment variables. Grant? [g/d (g = grant, d = deny)] g
# 環境変数へのアクセス権を取得したので、$HOME を参照できる
You have granted the "env" permission.
Your home dir is: /Users/developer
# 環境変数へのアクセス権を破棄したので、再度実行するとエラー
Failed to get the home directory: PermissionDenied: Requires env access, run again with the --allow-env flag

コマンドラインで補完の効かないオプションの付与が正直とても苦手なので、この API は多用してしまいそうです。

そのほか

そのほかの内容として以下のものがあります。

  • deno coverage カバレッジツールの改良
  • Deno.link 及び Deno.sumlink API が安定化
  • Deno.metrics API の内容がより細かくなった
  • deno fmt が JSON(.json .jsonc)をサポート
  • Deno.emit IIFE(即時実行関数式)でのバンドルをサポート
  • deno lsp の安定化
  • サポートする TypeScript が 4.2 にアップグレード

Deno 1.8 の代表的ななリリースは WebGPUAPI にやはりなるのだと思います。 ただ、機能提供された API とやりたいこととの乖離 がある利用者が大多数で、普段使うライブラリが WebGPUAPI に対応したら間接的に機能利用するというケースが多いように思います。

Deno が会社になり、新たに Deno deploy が公開されるなど、非常に動きが活発で驚くばかりです。 引き続き追いかけます。 (公開が遅れてしまい、Deno 1.9 が2021/04/13に公開になりました。近日 Deno 1.9 レポートも公開予定です。)

P.S.

■採用情報
yumenosora.co.jp

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

anchor.fm

■Twitterもフォローしてくださいね!
ツイッターでも随時情報発信をしています
twitter.com