denoが着々と開発されている

node作者であるRyan Dahl氏がアーキテクチャ設計におけるリベンジとして、nodeと同じくV8をスクリプトエンジンに採用して作ってるTypeScriptのネイティブ実行環境「deno」は、着々と開発されていて今や簡単にインストールできて、すぐ使えます。

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

ちょっと前までインストーラPythonだったのにそれも変わってた。Windows環境向けにはPowerShellで用意されています。

github.com github.com

nodeとの互換性を全否定してnpmを取り込まなかったので、エコシステムを発生からやり直しのため道のりは遠いと思いますが、すでにポツポツdenoを用いたライブラリやフレームワークが出現していました。denolibオーガナイゼーションにtypeormの空リポジトリがあったのが気になる。

denoのAPIリファレンスに見当たらなかったので正規表現はどうするのかなーと前々から思ってたのだけど、本体issueに要望リクエストが一切出てこないので不思議に思ってたら、実はサクっと動いた。

$ deno
> (() => {
  const m = '0123456789'.match(/(23).*(67)/);
  if (m) {
  console.log(m);
  }
  return 0;
  })();
[ "234567", "23", "67" ]
0
> exit();
$

バッチリ正規表現が使えました。なるほど正規表現ってV8のレイヤーで実装されているんですね。ECMAScriptの標準化範囲だから、そりゃそうかと。一方でファイルおよびネットワークのIOなどはdenoのレイヤーであって、そこだけリファレンスでは説明していました。

手元でファイル操作したりネット叩いたりするのに、普通ならPythonRubyとかでやるようなことを、これからはdenoでできるな。

ファイルの冒頭にこれまでshやpythonでやるように #!~/.deno/bin/deno と書いて、chmod +xしてみたけどそれでは「bad interpreter」エラーが出て動かなかった。#!deno でもダメで、#!/Users/masataka_k/.deno/bin/deno と書けば動く。「~」で動かないのはbashに詳しくなくてよくわからないけどホームフォルダの実名を書いちゃうとポータビリティが無くなるから、次のようにenvを通すようにした。

#!/usr/bin/env deno
(() => {
  const m = '0123456789'.match(/(23).*(67)/);
  if (m) {
    console.log(m);
  }
  return 0;
})();

超面白い。じゃあdenoの本質であるsandboxモデルはちゃんと効いてるか試すと...

#!/usr/bin/env deno
import { mkdir } from "deno";
(async () => {
  await mkdir("new_dir");
  return 0;
})();

以下のように聞かれます。

Deno requests write access to "new_dir". Grant? [yN]

いちいち聞かれないよう、一行目に #!/usr/bin/env deno --allow-write とドキュメント通りに書き込みを許可するフラグをつけるとOK。試してみたらシェルのカレントフォルダでAPIが動くので、上記スクリプトをパス通しておけば、普通にコマンドとして使える。面白い。

まとめとして、deno版のmkdirコマンドは以下の通り。

#!/usr/bin/env deno --allow-write
import { mkdir, args } from "deno";
(async () => {
  if (args.length === 2) {
    await mkdir(args[1]);
  }
  return 0;
})();

今後

開発目標に挙げられている、Top Level awaitはまだ実装されていません。

$ deno
> await deno.mkdir("new_dir");
SyntaxError: await is only valid in async function
>

これができると、コンソールで対話的に実行するのに無名関数で囲って実行するような手間が省ける。

  • Aims to be browser compatible.

ブラウザ互換性とは何か?元々のRyan Dhalのプレゼンテーションを解釈するに、ここでは機能として重なる場合にはブラウザでの振る舞いを優先するということなのですけど、詰めれば(プレゼンテーションでは直接そう言ってないけど)将来はdenoで書いたアプリケーションが簡単にブラウザで動くってことなのか?まずGlobalにロードされるブラウザ固有のオブジェクトにTypeScriptでアクセスする方法を用意するのと、今は~/.deno/genに出力しているトランスパイル結果を名前付け直して出力してあげるオプションを作るのかな?