create-babylon-appの開発調査
babylonjsのscaffoldingsが作りたい
create-vite的に、yarn create vite
でプロジェクト作成をする
参考にcreate-viteのプロジェクトを見てる
最新のリリースで、create-viteに追加されたcreate-electron-viteも参考になりそう
viteからこのパッケージを呼ぶようになっている
こうみるとcreate-viteとコードが似通っていることがわかる
つまりこの構成を参考にすればいいのかな
そもそも論、npm init(create)の仕組みを知ろうという
initのあとにパッケージ名を渡せるんだけど、それでコマンドを実行できるような仕組みっぽく
季報もいろいろあってパッケージの解決ができる
やはり時代はAI!()
ということで僕よりも優秀なChatGPT君に質問
create-viteのような、create-babylon-appというBabylon.js向けScaffoldingツールを作りたいのでその方法を教えてくださいと
最初は的外れだったけど、徐々に良さそうな回答をくれた
ディレクトリ構成
create-babylon-app/
├── package.json
├── bin/
│ └── create-babylon-app.js
└── templates/
└── default/
├── index.html
├── src/
│ ├── index.ts
│ └── game.ts
├── package.json
└── vite.config.ts
index.tsの中身
#!/usr/bin/env node
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import { program } from 'commander';
import execa from 'execa';
const access = promisify(fs.access);
const mkdir = promisify(fs.mkdir);
const copyFile = promisify(fs.copyFile);
async function copyTemplateFiles(templateDir: string, targetDir: string) {
const filesToCreate = await fs.promises.readdir(templateDir);
for (const file of filesToCreate) {
const origFilePath = path.join(templateDir, file);
const stats = await fs.promises.stat(origFilePath);
if (stats.isFile()) {
const contents = await fs.promises.readFile(origFilePath, 'utf8');
const writePath = path.join(targetDir, file);
await fs.promises.writeFile(writePath, contents, 'utf8');
} else if (stats.isDirectory()) {
await mkdir(path.join(targetDir, file));
await copyTemplateFiles(
path.join(templateDir, file),
path.join(targetDir, file),
);
}
}
}
program.version('0.0.1');
program.command('init <projectName>').action(async (projectName) => {
const targetDir = path.join(process.cwd(), projectName);
try {
await access(targetDir, fs.constants.R_OK);
console.error(`Directory ${targetDir} already exists`);
process.exit(1);
} catch (error) {
if (error.code !== 'ENOENT') {
console.error(error);
process.exit(1);
}
}
console.log(`Creating a new Babylon.js app in ${targetDir}.`);
await mkdir(targetDir);
const templateDir = path.join(__dirname, 'templates', 'babylon-app');
await copyTemplateFiles(templateDir, targetDir);
console.log('Installing packages. This might take a couple of minutes.');
await execa('yarn', ['install'], { cwd: targetDir });
console.log('App ready');
});
program.parse(process.argv);
chorkパッケージを使って、babylon-appを使うtsファイル
import { createProject } from './createProject';
import { Command } from 'commander';
import chalk from 'chalk';
import inquirer from 'inquirer';
const program = new Command('create-babylon-app');
program
.version('1.0.0')
.arguments('<project-name>')
.action(async (projectName: string) => {
const { confirm } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirm',
message: `Create a new Babylon.js project in ${chalk.green(projectName)}?`,
default: true,
},
]);
if (confirm) {
createProject(projectName);
} else {
console.log(chalk.yellow('Aborting...'));
}
});
program.parse(process.argv);
完成形ではないけどかなり近い形になっている気がするぞ
知見だなと思ったのが、npmパッケージとして作るCLIをテストする場合
ビルドした後にnpm linkをして、npm create xxxを実行することで動作確認ができるというもの
なるほどな~~~~
npm create xxxってローカルパッケージも含まれるのか
TypeScript CLI
よりも
nodejs CLI
のほうが検索結果的に合ったものが得られやすいな
TypeScriptでCLIを作ってnpmに上げるまでの記事
CLIのフレームワークについて言及はなく、どちらかというとnpmに関する内容が多い
create-viteではpromptsというフレームワークを使っていたんだけど、どうやら更新が2年前で止まってる
GitHubのissueもたまっているみたいだ
コマンドインターフェースはinquirerかなー
他の色付けとか引数パースとかは個々の記事を参考に使用
ある程度技術選定が済んだので、仕様策定をしたい感じがする
ceate-viteの場合、効かれる項目は以下
- Project Name
- framework
- framework variant
create-babylonも同じような構成でいいのかなと思ってる
- Project Name
- Build tool / bundler
- Vite
- Webpack
- variant
- TypeScript
- JavaScript
ビルドフローなどの整備をしていた
現状はビルドにtscを使い、dev実行にはvite-nodeを使用している
create-viteにならい、./index.jsで./dist/index.mjsを呼ぶ構成にしている
import "./dist/index.mjs"
今回はts-nodeの代わりにvite-nodeを使用している。試しに。
いったん処理フローなど整理したい感じもするけど、その前にinquirerの使いが手を確認しておくか
inquirerを入れて簡単なプロンプトの動作確認はできたが、ビルドする際にエラーになってしまっているよう
tsconfig.json
の設定が悪いのかもしれない
tsconfigのmoduleをESM2019にしたら普通にできた
ちなみにvite-nodeでは普通に動くから厄介
本日の進捗:
- フォルダーのコピーができるようになった
- vite-tsのテンプレを作成して動作できた
vite-jsのテンプレを用意し、CLIとして完成してきた
package.json
のnameをProjectNameに変更できるようになり、いよいよ
ファイル操作系はfs-extraがめちゃくちゃ使い勝手がいいな
だいたい完成してきたので、done is better than perferct ということで速くリリースしたいね
残る作業としては
- npmへ公開
- CI/CDの作成
- READMEの執筆
ActionsでCIを組んでみたが、なぜかPermission errorで止まる
2023-06-12T15:50:15.3342748Z npm notice Publishing to https://registry.npmjs.org/ with tag latest and default access
2023-06-12T15:50:15.6904028Z npm ERR! code E403
2023-06-12T15:50:15.6922186Z npm ERR! 403 403 Forbidden - PUT https://registry.npmjs.org/create-babylon-app - You may not perform that action with these credentials.
2023-06-12T15:50:15.6923241Z npm ERR! 403 In most cases, you or one of your dependencies are requesting
2023-06-12T15:50:15.6925408Z npm ERR! 403 a package version that is forbidden by your security policy, or
2023-06-12T15:50:15.6926062Z npm ERR! 403 on a server you do not have access to.
2023-06-12T15:50:15.6928441Z
2023-06-12T15:50:15.6930015Z npm ERR! A complete log of this run can be found in:
2023-06-12T15:50:15.6930841Z npm ERR! /home/runner/.npm/_logs/2023-06-12T15_50_14_576Z-debug-0.log
access tokenのパッケージへの読み書き権限をallにしたら治った
npmに公開!!
GitHubも公開!
投稿したForum