at backyard

Color my life with the chaos of trouble.

Deno 1.16のリリースノートを見ながら、いくつか少しだけ試してみる(備忘録)

Deno 1.16がリリース

Denoの1.16がリリースされた。

deno.com

最近Denoを触っているということもあって、1.16の変更点などを実際に試してみながらまとめてみようと思い書き始めたのだが、結局途中で体力が尽きてすべての変更は試していない。
(ちなみにまだまだDeno初心者なので、もっと良い書き方がある、理解が誤っている、などあればコメントください)

なお、Denoのupgrade方法は簡単で、下記のコマンドで完了する。

deno upgrade

ちなみに upgradeし終わったあとの私の環境はこんな感じ。

f:id:shinshin86:20211110213636p:plain
M1のMacBook Airで動かしている

目次

どのような変更点を試したのかが一覧でわかるように目次を載せておく。

fetchでファイルのURL取得もサポート

1.16からfetchを利用してローカルのファイルシステムからファイルの読み取りが行えるようになったらしい。
ファイルの読み取りを行う場合、パスはfile://から始まる絶対パスである必要がある。

ファイルの内容はチャンク単位で読み込まれるので、ファイル単位をメモリに読みことなく利用できるらしい。
リリースノートによると、大きいファイルをHTTPでストリーミングするには最適な方法だとのこと。

ひとまずローカルファイルを読み取るだけの簡単なサンプルを書いてみる。

下記のような記述の hello.txt を準備。

hello world!

次に書きのようなサンプルを書く。

// sample.ts
const resp = await fetch('file:///Users/{パスはフルパスで記述しているが、長いので省略}/hello.txt');
const text = await resp.text();
console.log({text});

下記で実行

deno run --allow-read sample.ts

下記のような結果となる。

{ text: "hello world!\n" }

ただ、公式のリリースノートにも記述があったように import.meta.url を利用することで相対的にパスを指定できる。
( import.meta.url を利用した場合、 file://から始まる方法で取得できるため、そのままこちらを利用してファイルパスの指定が行える。)

上のコードを import.meta.urlを使って書き直してみたものが下記となる。

import { dirname, join } from 'https://deno.land/std/path/mod.ts'

const filePath = join(dirname(import.meta.url), 'hello.txt');

const resp = await fetch(filePath);
const text = await resp.text();
console.log({text});

import.metaについては少し前にちょうど調べてこちらでもポストしていたので、リンクを貼っておく。

shinshin86.hateblo.jp

ファイルがみつからなかった場合などの挙動についてはリリースノート内に詳しく書かれていたのでそちらを参照してみてください。

新しいJSXトランスフォームをサポート

React 17から新しいJSXトランスフォームがサポートされているらしい。

あまりここらへんを理解していなかったので、公式のブログを読み返した。

ja.reactjs.org

リリースノートをほぼほぼなぞるだけなのであまり芸がないが、せっかくなのでDenoでreactのJSXトランスフォームを試してみる。

/** @jsxImportSource https://esm.sh/react */

function Welcome({ name }) {
  return (
    <div>
      <h1>Welcome {name}</h1>
    </div>
  );
}

console.log(Welcome("John"));

deno.json に下記の内容を書き込む。

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "https://esm.sh/react"
  }
}

これで下記を実行すると解釈されたコードが出力されていたのだが、色々と弄っていたら error: Import 'https://cdn.esm.sh/v54/@types/react@17.0.29/jsx-runtime...d.ts' failed, not found. というエラーが出てきて動かなくなってしまった。。。

原因を救命する体力はなかったため、とりあえずこれは飛ばす。

依存がおかしくなったりしてしまったんだろうか??まだDenoのそこらへんの仕組みをちゃんと理解していないので、ここについては後々調べてみようと思います。

New unstable signal listener API

OSのシグナルを読み取るための新しい(そして unstable な)APIが追加されたよう。 unstable とある通り、現在は実験的な段階のようで将来的に変更される可能性もあるようだ。

ちなみに既存のDeno.signals APIの代わりになるもののよう。

というわけで、Ctrl + C で処理を終了する簡単なサンプルコードを用意した。

// sample.ts
const listener = () => {
  console.log("SIGINT!");
  Deno.exit();
};

const sleep = (sec: number) => {
  return new Promise((resolve) => setTimeout(resolve, sec * 1000));
};

Deno.addSignalListener("SIGINT", listener);

let count = 0;
for (const _ of Array(10)) {
  count++;
  console.log(count);
  await sleep(1);
}

Deno.removeSignalListener("SIGINT", listener);

このコードは

deno run --unstable sample.ts

と実行することで動く。

1秒ごとに数字が表示されていくサンプルだが、Ctrl + Cを押すことで処理を中断できる。

ちなみに deno run sample.ts と動かしてみると、 Property 'addSignalListener' does not exist on type 'typeof Deno'. というようなエラーが出る。

--unstable 系のAPIを使う際にこのオプションを付けていないと、 --unstable をつけて!というエラーがでるが、単純なエラーとして出力されたのは意図したものだろうか?

追記: unstableに関するエラーメッセージを出すAPIについて

Denoのコードを読んでみてわかったことを追記する。

unstableに関するエラーメッセージを出すか否かの定義についてだが cli/diagnostics.rs内にあった。

const UNSTABLE_DENO_PROPS: &[&str] = &[
  ・
  ・
  ここにエラーメッセージを出すAPIが記載されている
  ・
  ・
];

どのような基準でこれらのAPIが選ばれているのかは分からない。

例えばDeno.setRaw はここでも定義されているし実際に--unstableをつけなかった際にもunstableに関するエラーメッセージがでるが、例えば Deno.flockなどはaddSignalListener同様に出ない。

以上

本当はほかの変更点も試してみようと思ったのだが、それを行うには残された体力は少なすぎたため、これで以上とする。