DenoのスクリプトからDeno実行環境のバージョンを確認し、古い場合に更新を促す方法
先日、以下のDenoteというサービスを作りました。
こちらのツールをCLIとしてもインストールできるようにしたのですが、そこでDenoのバージョンによるエラーが発生してしまいました。
これに対処するため、Denoのスクリプト内でDeno自体のバージョンを検査する処理を実装したので、やり方を紹介します。
--unstable
が必要な機能がある
問題:DenoのバージョンによってはDenoteでは、ローカルでの表示確認用にdenote serve
というコマンドを提供しています。
しかし、これを使用した際にDeno.serveHttp(...) is not a function
というエラーが出たという報告が上がりました。
Deno.serveHttp()
はDeno v1.13.0で正式リリースとなったAPIです。それ以前のバージョンでは--unstable
フラグを付けて実行する必要がありました。
Denoteでは、ユーザーがv1.13.0未満のDenoを使用していた場合、このエラーが発生します。
未だv1.13.0リリースから日が浅いため、これは対策を取らなければ再発しうると認識し、以下の二通りの対策を考えました。
-
denote
のインストールスクリプトに--unstable
をつける - ユーザーにDenoの最新版(というかv1.13.0以降)を使ってもらう
非常に感情的な理由なのですが、せっかく正式リリースになったのにわざわざ--unstable
フラグを付けるというのはスマートではないな、と感じます。
今回は2つめの方法を取り、これを検査する処理を追加することにしました。
対処:スクリプト内でDenoのバージョンを調べる
DenoのRuntime APIとして、Deno.version
という定数が用意されています。
ここにはdeno
とv8
とtypescript
というプロパティが含まれているので、Deno.version.deno
でDenoのバージョンを取得できます。
こうして取得したDenoのバージョンと、スクリプト内で保持する要求最低バージョンとの比較を行います。
バージョンナンバーの文字列の比較になるので、semverモジュールを使うことにしました[1]。
具体的には以下のような処理を実装しています。
export { lt as semverLessThan } from "https://deno.land/x/semver@v1.4.0/mod.ts";
const MINIMUM_DENO_VERSION = "1.13.0";
if (semverLessThan(Deno.version.deno, MINIMUM_DENO_VERSION)) {
console.error("The Deno version you are using is too old.");
console.error(`Please update to Deno ${MINIMUM_DENO_VERSION} or later.`);
console.error("To do this run `deno upgrade`.");
return 1;
}
// 以下略
Deno.version.deno
がMINIMUM_DENO_VERSION
未満のバージョンの場合、エラーメッセージを表示して終了しています。
実際のファイルはこちらです[2]。
なお、この実装はDeno Deployのローカル実行ツールであるdeployctlを参考にしました。
おわりに
v1.13.0でNative HTTPが正式リリースとなったことで意気揚々と導入したのですが、全てのユーザーが更新に対応できているとは限らない…ということに想像が至っていませんでした。
環境依存の問題というのは公開してみないと表面化しづらいということもあるので、早々に判明してよかったと思っています。
また、今回のように自作ツールに重要な更新を加えても、その更新がユーザーの環境に反映されなければ、これもまた意味がありません。
上記で紹介したdeployctlには、「deployctl自身の更新を監視する機能」と「deployctl自身を更新するサブコマンド」があるため、こちらも導入したいと考えています。
Discussion