もしあなたがBashスクリプトをじっと見つめて「もっと良い方法があるはずだ」と思ったことがあるなら、仲間入りです。

Glintecoでは、多くの内部自動化、開発設定スクリプト、デプロイフロー、バックアップ、Dockerオーケストレーションヘルパーを管理しています。しばらくの間、Bashをデフォルトとしていましたが、スクリプトが複雑になるにつれて、限界を感じるようになりました。引用符地獄、貧弱なエラー処理、構造の欠如です。そこで登場したのがzx、Node.jsベースのツールで、シェルスクリプトの作成を本当に楽しくしてくれます。

なぜ私たちがほとんどのスクリプトニーズにzxを使用するようになったのかを見ていきましょう。

zxとは何か?

Googleのチームによって作成されたzxは、JavaScript(またはTypeScript)でシェルスクリプトを作成できるライブラリです。await可能なシェルコマンド、fs、os、globなどのビルトインユーティリティなどの超能力を持つNode.jsと考えてください。

従来の:

#!/bin/bash
echo "Hello, $1"

代わりにこう書きます:

#!/usr/bin/env zx
console.log(`Hello, ${process.argv[2]}`);

そして、突然あなたのスクリプトは読みやすく、テスト可能になり、保守可能になります。

なぜBashをzxに切り替えたのか

1. 読みやすく、使い慣れた構文

私たちのチームのほとんどは、すでにJavaScriptとTypeScriptに精通しています。zxを使用することで、次のような構文の奇妙さに苦しむ必要がなくなります。

if [[ -z "$VAR" ]]; then ...

今ではこう書きます:

if (!process.env.VAR) { ... }

2. Async/Awaitが無料で利用可能

&を使ってBashプロセスを並列化し、それらを待ち、エラーをクリーンに処理しようと試みたことがありますか?私たちはしました。ひどいものでした。

zxを使用すると、次のようにします。

await Promise.all([
  $`command1`,
  $`command2`
]);

簡単です。ビルトインの簡単な並行処理です。

3. より安全でクリーン

Bashでは、エスケープされていないスペースや忘れられた引用符がシステムを破壊する可能性があります。zxでは、`$``文字列補間は、引数をデフォルトで安全にエスケープします。

const branch = 'main';
await $`git checkout ${branch}`;

インジェクションや奇妙な文字について心配する必要はありません。

4. 標準ライブラリの良さ

あなたは手に入れます:

  • fs、path、osモジュール
     

  • chalk、globby、yamlなど
     

  • トップレベルのawait

設定を読み込んで使用したいですか?簡単です:

import fs from 'fs/promises';
const config = JSON.parse(await fs.readFile('./config.json', 'utf8'));

5. クロスプラットフォームフレンドリー

Bashは常にBashとは限りません。(macOS対Linux対Windows上のGit Bashを見てください。)

Node + zxを使用すると、スクリプトはNodeが実行されるすべての場所で同じように実行されます。開発者のオンボーディングやCI/CDパイプラインの自動化を行う際には、これは大きなメリットです。

実用例:私たちの開発セットアップスクリプト

以前:

#!/bin/bash
echo "Setting up..."
cd backend || exit 1
pip install -r requirements.txt
cd ../frontend || exit 1
npm install

その後:

#!/usr/bin/env zx

await $`cd backend && pip install -r requirements.txt`
await $`cd ../frontend && npm install`

console.log(' Setup complete!');

PythonやNodeのバージョンがないかどうかのチェックを追加し、ユーザーフレンドリーなエラーをスローしましたが、JSの方がはるかに簡単でした。

欠点?

正直に言うと、いくつかのトレードオフがあります。

  • Node.jsがインストールされている必要があります。
     

  • 非常に小さなスクリプトの場合、Bashよりもパフォーマンスがわずかに低くなります。
     

  • Nodeが許可されていない場所(例:厳格なCIコンテナ)では実行できません。

しかし、私たちのユースケースの95%では、利点が欠点をはるかに上回っています。

最終的な考え

私たちはまだ小さなワンライナーにはBashを使用しています。しかし、10行を超えるものについては、zxが(断然)優れています。読みやすく、強力で、正気を犠牲にせずにスクリプトを作成できます。

多くのスクリプトを作成していて、チームがすでにJavaScriptまたはTypeScriptに精通している場合は、zxを試してみてください。おそらく二度と戻らないでしょう。