created: 2024-06-19T07:53:53.665Z
zx と node:test のおかげでちょっとしたスクリプトは nodejs/mjs で書くとラク
zx
を使い始めたおかげでシェルスクリプトを書くことが減った。
だいたいのプロジェクトで nodejs はなんかしら使うので、mjs ファイルに zx
を import して使うことが多い。
nodejs にビルトインのテストツールが入っていて、完全な TDD をするというよりもちょっとした動作確認にこれがけっこう便利なのでよくつかっている。
引数が 3 つ以上あったり、細かい文字列操作がしたいスクリプトは mjs で書くほうが楽だと思う。
--test
オプションを用意する
zx.argv.test
で処理を切り分けている。
import { argv } from "zx";
...(実装)
if (argv.test) {
runTests();
} else {
main(argv);
}
こんな実行でテストのみの実行になる
./cli.mjs --test
node:test
がだいたいできる
jest でよく使うものはだいたいある。
引数エラーのテスト
たとえば ctx.mock.method(process, "exit")
とかすればちょっと面倒だけどプロセスの異常終了時のテストができる。
import test, { describe } from "node:test";
function runTests() {
describe("parseArgs", () => {
test("--table option is mixed and recentDays is set", (ctx) => {
// mock
const { mock } = ctx.mock.method(process, "exit");
mock.mockImplementationOnce(() => {});
// exec
parseArgs({ ... });
// verify
assert.match(
mock.calls[0].arguments[0],
/Validation error: --recent-days is not support log and non-log tables are mixed/
);
});
});
}
zod で引数をチェックする
zod
はだいたいのプロジェクトでつかっているのでヌルッと import できる。
import { z } from "zod";
import { fromError } from "zod-validation-error";
...
const result = argSchema.safeParse(...);
if (!result.success) {
console.log(chalk.red(fromError(result.error).toString()));
process.exit(1);
}
zod のエラーメッセージそのままだとコマンドラインツール的には読みにくい。引数エラーは zod-validation-error
というので文字列に変換すると完璧ではないけどだいぶ読みやすくなってよかった。
こんなかんじ
Validation error: Expected string, received boolean at "loginPath"
その他
shebang を工夫したら typescript/ts-node で実行できないかなと思っている。 しかしチームで作ってるやつだと ts-node をグローバルに入れてもらうのは大変そうなのでこれはやってない。