Hygenを使用して対話形式でファイルを生成するのを試した
Hygenとは
hygenは、シンプルで、高速で、スケーラブルなコードジェネレータです。
この記事でやること
Hygenを使用して、対話形式でファイルが生成されるようにします。
今回作成したいファイルと実際の対話の流れは以下の通りです。
💻 ・・・ 質問
🙋♂️ ・・・ 開発者
-
対話の流れ
💻 ? What is the directory name?
🙋♂️ > Button
💻 ? What is the component name?
🙋♂️ > Button
💻 ? Do you want to create a types.ts file? (y/N)
🙋♂️ > y -
生成されるファイル
src/components/ui/Button/Button.tsx
src/components/ui/Button/Button.stories.tsx
src/components/ui/Button/types.ts
必要な手順
- Hygenをインストールする
- Hygen設定ファイルの作成をする
- 自動生成したいファイルの設定をする
- package.jsonにhygenコマンドを追記する
- コマンドを実行してみよう
Hygenをインストールする
まずはHygenをインストールしましょう
npm i -D hygen
Hygen設定ファイルの作成をする
Hygen設定ファイルを作成します。
touch .hygen.js
module.exports = {
templates: `${__dirname}/hygen`,
};
自動生成したいファイルの設定
自動生成したいファイルの設定を定義するファイルを格納するためのディレクトリを作成します。
mkdir -p hygen/component/create
hygen/component/create/ 配下にプロンプト(対話の流れ)と自動生成したいファイルの定義をしていきます。
※ファイルの内容はそれぞれ適宜好きなように変更してください
module.exports = [
{
message: 'What is the directory name?',
name: 'directory_name',
type: 'input',
validate: (answer) => {
if (answer !== '') {
return true
}
},
},
{
message: 'What is the component name?',
name: 'component_name',
type: 'input',
validate: (answer) => {
if (answer !== '') {
return true
}
},
},
{
message: 'Do you want to create a types.ts file?',
name: 'should_create_types_file',
type: 'confirm',
},
]
---
to: src/components/ui/<%= directory_name %>/<%= component_name %>.tsx
unless_exists: true
---
type Props = {
text?: string;
}
export const <%= component_name %> = ({text}: Props) => {
return <div>{text}</div>;
};
---
to: src/components/ui/<%= directory_name %>/<%= component_name %>.stories.tsx
unless_exists: true
---
import { ComponentStory, ComponentMeta } from '@storybook/react'
import { <%= component_name %> } from './index'
export default {
title: 'Components/<%= component_name %>/<%= component_name %>',
component: <%= component_name %>,
argTypes: {
backgroundColor: { control: 'color' },
},
} as ComponentMeta<typeof <%= component_name %>>
const Template: ComponentStory<typeof <%= component_name %>> = (args) => (
<<%= component_name %> {...args} />
)
---
to: "<%= should_create_types_file ? `src/components/ui/${directory_name}/types.ts` : null %>"
unless_exists: true
---
ファイルの構成要素
ファイル上部のコードフェンス(---)で書かれている部分であるフロントマター、実際に生成されるコードの部分であるテンプレートボディで構成されます。
-
フロントマター
- ファイル上部の[--- hoge ---]で書かれている部分のこと
- メタデータを定義する
-
テンプレートボディ
- 実際に生成されるコードの部分のこと
- ejsというテンプレートエンジンを使用して記述します
フロントマターで扱えるメタ情報・ejsについては以下を参照してください。
条件付きレンダリング
types.ts.tでは条件付きレンダリングされるようにしています。to: に対してnullを指定するとそのテンプレートの出力をスキップできます。
"Do you want to create a types.ts file?"の質問に対して「y」だと新規にファイルを作成し、「N」だと作成しないようにしています。
package.jsonにhygenコマンドを追記する
"create:component": "hygen component create"
コマンドを実行してみよう
npm run create:component
? What is the directory name?
> Button
? What is the component name?
> Button
Loaded templates: hygen
added: src/components/ui/Button/Button.stories.tsx
added: src/components/ui/Button/Button.tsx
ファイルが作成されました🎉
参考にさせていただいた記事
最後に
内容は気まぐれで随時更新します。
間違っているところがあればコメントで教えていただけますと幸いです🙇♂️
Discussion