Movable Type の ベーステーマ / MTAppjQueryのuser.js/user.cssを生成するCLIを作った
Movable Typeで利用する雛形テーマを生成するCLIを作りました。
作ったきっかけ
MTMLを作成するときにいつものように、 mt-theme-starterkit からダウンロードして、コピーして利用していました。
元々ベーステーマはリポジトリを公開しており、やろうと思えば npm(無料の範囲)にpublishできる状態でした。
今回は業務の効率化?(開発環境の用意)を図り npm に公開しました。
今回は、CLIを作ってみたい欲求もあり足場ツールを見直して、npx mt-theme-starterkit
で利用できるようにした。
MTでテーマを作りたい人向けのツールではあるので、需要はないかもしれません。(あくまでも自分用で開発しました)
Movable Type 8 からは テーマ機能もアップデートされていくことのようですので、作ったテーマのリポジトリとの相性も良くなっていくと期待しています。
どんなCLIを作ったのか?
一言にまとめると 対話式のCLI
です。
よく Next.js や Nuxt.js といったフレームワークには、 npx create-next-app@latest
といった開発環境を作るCLIがあります。
Next.jsやNuxtとったフレームワークを利用したことがあればイメージはつきやすいです。
この 対話式のCLI
の Movable Type Theme を npx 経由でインストールできるようにしました。
なにができるか?
現状できることは2つです。
自分のテーマと必要に応じて MTAppjQueryで利用する user.js / user.css の雛形ファイルを生成できます。
- 選択方式でテーマを選び、選択したテーマを生成
- MTAppjQueryの利用有無で user.js /user.css を生成
前提条件
以下のNodeのバージョンがインストールされていることが前提です。
- node 20.10.0 以上
- npm 10.2.3 以上
使い方
// インストールしたいディレクトリに移動
npx mt-theme-starterkit
npx mt-theme-starterkit を実行すると、対話式のCLIが起動します。
? Do you have MTAppjQuery installed? (Y/n) Y
? Select a theme to generate: (Use arrow keys)
❯ theme-starter
? Enter the output directory: (mtml)
? Select a user-file to generate: (Use arrow keys)
❯ base-userfile
? Enter the output user-file directory: (user-file)
- MTAppjQueryを利用しているか Y / n で選択
- 利用したいテンプレートを選択(現在は一つのみ)
- 出力先のディレクトリを入力(デフォルトは mtml)
- user.js / user.css を利用するか選択(現在は、base-userfileのみ) ※1でnを選択した場合はスキップされます。
- 出力先のディレクトリを入力(デフォルトは user-file)
生成後
- ./CLIを実行したカレントディレクトリ
- mtml(デフォルトの場合)
- テーマの雛形ファイル
- user-file(デフォルトの場合)
- user.js / user.css の雛形ファイル
- mtml(デフォルトの場合)
CLIの開発
試しに作ったCLIのため、コードとしては main.ts で作りました。
TypeScriptで実装したため、公開前やCLIの実行テストするときは npx tsc --build
でコンパイルする必要があります。
実行すると、 dist/main.js
が生成されます。
手元でテストするときは、 node dist/main.js
で実行できます。
npx tsc --build
node dist/main.js
利用技術
- TypeScript
- inquirer
- commander
- fs-extra
TypeScript
最近ではTypeScriptで記述することがほとんどになってきたため、コンパイルを行う手間はありますがTypeScriptで実装しました。
inquirer
対話式のコマンドラインインターフェースをを実装しやすくするために inquirer.js を利用しました。
inquirerをインストールすることで、prompt関数が用意されており配列・オブジェクトを渡すことで対話式のインターフェースを実装できます。
import inquirer from 'inquirer';
const answer = await inquirer.prompt([
{
type: 'confirm',
name: 'installed',
message: "Do you have MTAppjQuery installed?"
}
]);
return answer.installed; // true or false
commander
コマンドラインアプリケーションを簡単に利用できるためのライブラリとして commander.js を利用しました。
コマンドラインツールの開発が容易になり、構造化されたオプションや引数を受け取ることができます。
以下のコードでは --dry-run
というオプションを受け取ることができます。
import { program } from 'commander';
program.option('-d, --dry-run', 'dry run');
program.parse();
const options = program.opts();
main(options.dryRun);
今後の予定
- Node ユニットテストの勉強するためにテストを書く
- テーマの雛形ファイルを増やす
- user.js を TypeScriptに書き換えをする
- main.tsのリファクタリング(型定義周り)
Discussion