Viteのテンプレート選択ができない?Vite-createrが登場!

この記事は「掘金・启航计划」に参加しています。

プロジェクトの背景

Viteが登場してから、webpackのユーザーの多くを引き継ぎました。初心者でもすぐにViteの高速性を体験できます。

Viteの公式ドキュメントでは、その名前の由来について述べられています。Vite(フランス語で「速さ」)という名前通り、すべての要素が「速さ」を強調しています。

しかし、vue-cliに慣れた開発者(私自身も)にとって、テンプレートの選択を記録できないツールは受け入れがたいものがあります。毎回、テンプレートの選択やJavaScriptかTypeScriptの選択が必要なのは、ストレスです。公式ではコミュニティが維持しているテンプレートであるawesome-viteが提供されていますが、それらは初心者には理解しづらいものばかりです。

こうした問題を解決するため、便利なツール「vite-creater」が生まれました。GitHubのソースコードはこちら 👉 クリックしてアクセス

vite-createrとは?

vite-createrは、Viteプロジェクトを自動的に作成するCLIツールです。ユーザーが定義したプロセスに従って、プロジェクトの作成から依存関係のインストールまでを自動化します。vite-createrが完了を通知すれば、すぐにnpm runが実行できる状態になります。内部的にはnpm create viteを使用しており、フレームワーク以外のすべての処理は自動で行われます。あとは事前に設定したテンプレートを選ぶだけです。

vite-createrは必要ですか?

もしVueの経験者が使いこなしているのであれば、このツールは役立つかもしれません。vue-cliのように、自分用のテンプレートを保存し、カスタムライブラリを含めることも可能です。

一方、Viteの基本機能をそのまま使いたい場合は、vite-createrは不要かもしれません。ただし、ぜひ試してみてください。vite-createrはViteのアップデートとともに進化していきます。

vite-createrの使い方

インストール

npm i vite-creater -g

開始手順

vcreater init <yourProjectName>

vite-createrには、デフォルトのテンプレートが内蔵されています。最も一般的で、開発しやすい構成です。そのままEnterキーを押すだけでプロジェクトが生成されます。

もし好みのテンプレートがない場合、「カスタムプロセスへ移動」を選択できます。

カスタム設定

vite-createrは、CSSプリプロセッサ、JavaScriptかTypeScriptの選択、vue-routerの使用、vuexまたはpiniaの選択など、一般的な設定を尋ねます。

(vite-createrの現在のバージョンでは、Vueのパッケージのみに対応しており、他のフレームワークを使う場合は「いいえ」を選択し、カスタムパッケージ欄に必要なパッケージを追加してください。)

さらに、追加のサードパーティパッケージの選択を求められます。たとえば、大画面対応ツール「vue-autofit」を使用したい場合は、入力欄に「vue-autofit」と入力します。

最後に、この設定を保存するかどうかを尋ねられます。名前を付けることもできますし、しないことも可能です。保存された設定は、依存関係と使用言語が表示されるリストに含まれます。

もしvite-createrがフレームワークの選択を求めたら、必要に応じて選択してください。

フレームワークを選択すると、プロジェクトが即座に作成され、カスタムパッケージもインストールされます。

保存されたテンプレートの利用

一度設定を保存した後、次回からは保存されたテンプレートが一覧表示され、選択するだけでプロジェクトが生成されます。選択の手間が省けます。

vite-createrの実装方法

vite-createrはNode.jsで作られています。

Node.jsのCLIアプリケーションは、Node.js環境でのみ動作します。なぜなら、Node.jsのCLIはV8エンジンによって実行されるためです。グローバルにインストールされたCLIは、環境変数に自動的に追加され、JavaScriptコードが実行される際にはNode.jsがOSとやり取りを行います。そのため、内部動作の詳細を知らなくても、JavaScriptの書き方さえわかれば問題ありません。

開発に必要なライブラリ

  • commander: "^10.0.1" - DOSコマンドを実行可能
  • inquirer: "^9.2.0" - インタラクティブな入出力を行う
  • configstore: "^6.0.0" - ローカルに設定を保存(cookieやlocalStorageのようなもの)

開発手順

プロジェクト初期化

npm init

プロジェクトの基本情報を入力し、標準的なnpmパッケージを初期化し、package.jsonファイルを作成します。

注意点として、npmに公開する場合は、同じ名前または類似名のパッケージが既に存在しないか確認してください。存在する場合は、ユニークな名前または@username/プレフィックスを付ける必要があります。

commanderでコマンド初期化

import { program } from 'commander';
program
  .version('1.0.0')
  .description(`vite-createrはViteプロジェクトを素早く作成するためのスキャフォールディングツールです`);

program
  .command('init <projectName>')
  .description('vite-createrを使ってプロジェクトを作成')
  .option('-p, --projectName <string>', 'プロジェクト名')
  .action(async (initProjectName) => {
    await askForOptions(initProjectName) // 任意の質問関数を呼び出す
  });
program.parse(process.argv);

Node.jsのCLIでは、async/awaitを使って処理をブロックし、ステップの完了やユーザー入力を待機できます。

inquirerでインタラクティブな質問

import inquirer from 'inquirer';

let preSetRules = [
    {
      name: 'selectRule',
      type: 'list',
      message: '予め定義されたルールを選択するか、カスタムプロセスに移動してください',
      choices: preSetRulesList, // 文字列の配列のみを受け入れる
    }
  ]
 let isPreSetRules = await inquirer.prompt(preSetRules)

このコードは、矢印キーで選択可能なリストを表示します。

configstoreで設定を保存

import Configstore from 'configstore';
const conf = new Configstore('vite-creater');
conf.set("customRulesList", customRulesList); // キーとデータを設定
let customRulesList = conf.get('customRulesList');

customRulesListには配列、オブジェクト、文字列などが格納でき、cookieのような使い方ができます。

child_processでサブプロセスの制御

import { exec } from 'child_process';
function execCreateTs(command) {
  console.log('exec:', command);
  return new Promise((resolve, reject) => {
    const child = exec(command, (err, stdout, stderr) => {
      if (err) {
        console.log('err::: ', err);
        reject(err)
      }
    })
    child.stdout.on('data', async data => {
      if (data.includes('Package name')) {
        process.stdout.write('\x1b[32m' + data + '\x1b[0m');
        child.stdin.write('\n');
      }
      if (data.includes('Vue')) {
        process.stdout.write('\x1b[2J\x1b[0f');
        process.stdout.write('\x1b[32m' + data + '\x1b[0m');
        clearAnimation()
        selectFramework(child)
      }
      if (data.includes('TypeScript')) {
        process.stdout.write('\x1b[32m' + data + '\x1b[0m');
        process.stdout.write('\x1b[2J\x1b[0f');
        child.stdin.write('\n');
        resolve(child.stdout)
      }
      if (data.includes('is not empty')) {
        console.log('\n\x1b[31m×\x1b[0m ディレクトリは既に存在します');
        process.exit();
      }
    })
  })
}

この例はTypeScriptプロジェクトの作成における処理です。サブプロセスの出力内容を監視し、条件に応じて次のステップに進むようにします。

selectFrameworkメソッドは、Vueが表示された際に呼び出され、フレームワーク選択の段階に入ったことを示します。これにより、ユーザーは直接選択できるようになります。

async function waitUserPresskey() {
  return await new Promise((resolve, reject) => {
    process.stdin.setRawMode(true);
    process.stdin.resume();
    process.stdin.on('data', (key) => {
      key = key.toString('ascii');
      resolve(key)
    });
  });
}
async function selectFramework(child) {
  let input = await waitUserPresskey();
  if (input === '\u0003') {
    process.exit();
  }
  child.stdin.write(input);
}

このメソッドはユーザーからの入力待ちを行い、それをサブプロセスに転送します。これにより、ユーザーが選択するまで繰り返し操作が続きます。

自動化された処理

上記の手順で、Vite + Vueのプロジェクトが作成されます。続いて、npm installを実行し、カスタムパッケージをインストールします。


    await execNpmInstall('npm i')
    await execNpmInstall(installCommand)
function execNpmInstall(command) {
  console.log('exec:', command);
  return new Promise((resolve, reject) => {
    const child = exec(command, (err, stdout, stderr) => {
      if (err) {
        reject(err)
      }
    })
    child.stdout.on('data', async data => {
      if (data.includes('packages in')) {
        console.log('\n', data);
        resolve(child.stdout)
      }
    })
  })
}

保存されたサードパーティパッケージは、conf.get('xxx')で取得し、インストール処理に渡すことができます。

完了

以上がvite-createrの開発概要です。これらの機能を統合し、npmに公開することで、完全なツールとして完成させることができます。npmアカウントにログイン後、npm publishコマンドで公開できます。

vite-createrのnpmページはこちら 👉 vite-createrのnpmページ

GitHubでのオープンソースはこちら 👉 GitHubリポジトリ

結論

妥協は許されません!

タグ: Vite CLI Node.js Vue javascript

7月13日 23:40 投稿