Deno CLI コマンド作成 最速 方法 20231218
この記事は前に書いた記事の抜粋かつ修正版
簡単にライブラリを呼び出すコマンドを作るとなったら、やはり deno + zx(or dux) だと思う。権限管理があって、ファイル単体でモジュールを解決して実行できる。
tl;dr
-
~/bin/mycmd
の単体ファイルでコマンドを作成する - shebang に deno permissions を与えて chmod +x する
-
node:util
のparseArgs
でDeno.args
をパース - dax でコマンドを実行
実装
~/bin
等にパスを通してあるとする。
雛形。
#!/usr/bin/env -S deno run -A --ext=ts
import { parseArgs } from "node:util";
import $ from "https://deno.land/x/dax@0.36.0/mod.ts";
// コマンド実行時に > ls みたいな形で出力する
$.setPrintCommand(true);
// 引数のパース
const parsed = parseArgs({
args: Deno.args,
options: {}
});
// run
await $`ls`;
これを
# $ code ~/bin/myls ファイルを編集
$ chmod +x ~/bin/myls
$ myls # run!
> ls
myls
みたいな感じで実行する。
以下解説
単体ファイルで完結
~/bin
の下で実行コマンド以外を散らかしたくないので、 deno スクリプトを一つ置いて完結させる。
chmod +x
で実行権限を与えて、拡張子を省略して実行するのを想定しているが、その際に ts shebang で --ext ts
を与えておく必要がある(省略した場合は js として実行)。権限の制御が必要なら shebang に -A
ではないパーミッションを書く。
テストが必要ならばスクリプト内で Deno.test
を書いてテストする。
if (import.meta.main) {
// run
await $`ls`;
}
Deno.test('test', () => {
// test here
});
dax でコマンド実行
前回の記事では npm:zx
で作ったが、これはnodeで様々なユーティリティを同梱してるために、色々と余計な権限を要求してくる。
今回は dax を使った。
$ deno eval 'import $ from "https://deno.land/x/dax@0.36.0/mod.ts";$.setPrintCommand(true); await $`ls`;'
> ls
args.ts cfai-text cmd
とはいえ dax の要求する --allow-run
は細かい工夫を吹き飛ばすほどの強い権限なので、よく考える必要はある。ファイルの読み書き程度なら dax ではなく --allow-read/--allow-write
で書き直す。
Deno v1.39 - node:util's parseArgs
Deno の公式の flags 非常に使いづらく困っていたのだが、 Deno v1.39 で node:util の parseArgs がサポートされた。
これは自分が Node.js で愛用していたもので、 Node.js の標準ライブラリとして提供されていて TypeScript でいい感じに型が付く CLI パーサーになっている。
Parsing command line arguments with `util.parseArgs()` in Node.js
というか自分が Issue 立てて実装してもらって、やっとリリースされた。それで嬉しくなってこの記事を書いている。
npm:zx
が minimist 相当の CLI パースを同梱していたが、型がつくインターフェースではないし、parseArgs の方が Node 標準ライブラリの機能で使いやすい。
deno install との違い
今回のハック以外のコマンドを作る方法として、deno install コマンドでも deno スクリプトを CLI 化することはできる。
$ deno install --allow-read -f foo.ts # ~/.deno/bin/foo
$ foo # 拡張子を省略したコマンド名でインストールされる
これでも別に構わないのだが、自分はソースの変更毎に deno install し直すのが面倒だった。
複数のファイルで構成されるぐらいの複雑度のCLIコマンドを作ってるときは deno install で、1ファイルで完結する書き捨てのファイルなら今回の方式でやっている。
利点として、挙動を変更したくなったらその場でエディタで開いて編集できる。
おわり
何人かにこの自己流のやり方を紹介したら好評だったので記事にした。
Discussion