🐣

Hygenを使えばコンポーネント作りがちょっとだけ楽になる話

2022/11/07に公開

コンポーネントを作るときって割といろんなファイルを作る必要がありますよね。tsxはもちろん、cssとか、storiesとか、testとかとか。コンポーネントを作るたびに毎回作ったりするのも面倒ですよね。
そんなときに便利なのが今回ご紹介するHygenになります。

Hygenでどんなことができるの?

Hygenは対話形式のコードジェネレーターです。あらかじめ決めた質問に回答していけば、作成したテンプレートに沿ってファイルが出力されるものになります。

例えばコンポーネントを作る際に以下のような構成でButtonコンポーネントを作りたいとします。

components
└─ atoms
   └─ Button
       ├─ index.module.css
       ├─ index.stories.tsx
       ├─ index.test.tsx
       └─ index.tsx

Hygenを使うと以下のような手順でButtonコンポーネントを作ることができます。

  1. 登録しているスクリプトを実行
yarn gen:fc
  1. 設定しておいた質問に答える
✔ please enter the name · Button
✔ please enter the path · src/components/atoms
✔ please check what you need · style, story, test
  1. ファイルが生成される
added: src/components/atoms/Button/index.module.css
added: src/components/atoms/Button/index.stories.tsx
added: src/components/atoms/Button/index.test.tsx
added: src/components/atoms/Button/index.tsx

以上となります。
では次から実際にHygenを実行するまでの手順を解説していきます。

Hygenを実行するまでの手順

  1. Hygenのインストール
yarn add -D Hygen
  1. ディレクトリとファイルの作成
    ルートディレクトリに_templatesディレクトリを作成し、その中に設定ファイル(index.js)とテンプレートファイル(*.t)を作成します。
_templates
└─ component
   └─ new
      ├─ index.js
      ├─ template.component.t
      ├─ template.stories.t
      ├─ template.style.t
      └─ template.test.t
  1. スクリプトの作成
package.json
"scripts": {
  "gen:fc": "hygen component new",
}
  1. 質問を設定
_templates/component/new/index.js
module.exports = {
  prompt: ({ inquirer }) => {
    const questions = [
      {
        message: 'please enter the name',
        name: 'componentName',
        type: 'input',
        hint: 'Button',
      },
      {
        message: 'please enter the path',
        name: 'path',
        type: 'input',
        hint: 'src/components/atoms',
      },
      {
        message: 'please check what you need',
        name: 'needList',
        type: 'select',
        choices: ['style', 'story', 'test'],
        multiple: true,
        hint: 'press space key to toggle check',
        initial: ['style', 'story', 'test'],
      },
    ];

    return inquirer.prompt(questions).then((answers) => {
      const { componentName, path, needList } = answers;
      const needStyle = needList.includes('style');
      const needStory = needList.includes('story');
      const needTest = needList.includes('test');
      return { componentName, path, needStyle, needStory, needTest };
    });
  },
};
  1. 各テンプレートファイルを作成
    ここではテンプレートのひとつであるtemplate.stories.tについて解説します。
_templates/component/new/template.stories.t
---
to: "<%= needStory ? `${path}/${componentName}/index.stories.tsx` : null %>"
---
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { <%= componentName %> } from './<%= componentName %>';

export default {
  title: '<%= componentName %>',
  component: <%= componentName %>,
} as ComponentMeta<typeof <%= componentName %>;

const Template: ComponentStory<typeof <%= componentName %>> = (args) => <<%= componentName %> {...args} />;

export const Default = Template.bind({});
Default.args = {
  // write props
};
  1. コマンドを実行
    ここで冒頭でも書いたコマンドを実行することで、あとは回答していくだけでファイルが生成されます。
yarn gen:fc

さいごに

Hygenは公式も含めドキュメントがあまり充実しておらず、いろいろしようとすると調べるのに時間を要します。Issuesに割とお目当ての内容が転がってたりもするので、根気強くググって見てください。
ただ、あまり凝ったことをやろうとするとテンプレートの見通しが悪くなるので、良い塩梅を見つけることをおすすめします。例えば今回のサンプルではスタイルが必要か等を聞いたりしてますが、私は実際には有無を言わさず出力して、不要なら消す運用にしています。その方がテンプレートやindex.jsもシンプルになり保守が楽になるからです。
用法用量を守ってお使い頂くことでコーディングの頼れるお供になりますので、ぜひHygenをお試しあれです💪🏻

まとめ

  • 質問を作る
  • 回答する
  • ファイルができる!!

Discussion