この記事は「掘金・启航计划」に参加しています。
プロジェクトの背景
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リポジトリ
結論
妥協は許されません!