jsコードジェネレータ hygen でReactのコンポーネントの雛形ファイルを自動生成する

July 23, 2019

Reactのプロジェクトで作業をしているとコンポーネントクラスを毎回コピペで作るのが辛くなってきます。(Reactに限った話ではないですが)

コードジェネレータでワン・コマンドで作れないかなーと思って探してみるとありました。

GitHub - jondot/hygen: The simple, fast, and scalable code generator that lives in your project.

これを使うとテンプレートを記述しておけば簡単にコンポーネントの雛形を作ってくれます。

インストール

npm i -D hygen

生成したいファイル

コンポーネントの他にもstorybook用のstoriesファイルも生成したいです。

./src
└ components
  └ atoms
    └ Component.tsx
    └ Component.stories.tsx

テンプレートの作成

拡張子の末尾に.tがつくのがテンプレートファイルです。

./_templates
└ components
  └ add
    └ component.tsx.t
    └ component.stories.tsx.t
    └ prompt.js

パラメータの挿入

テンプレートファイルでは(component.tsx.t)、<%= hoge %>と書くとパラメータを挿入することができます。

---
to: src/components/<%= atomicDirectory %>/<%= componentName %>.tsx
---
import React from "react";

const <%= componentName %> = () => {
  return (<></>
  );
};

export default <%= componentName %>;

コンポーネント名などの値はprompt.jsで入力フォームみたいなものを作ることができます。ここではatomic designのディレクトリとコンポーネント名を入力することができます。質問の形式はenquirerに使えるものが揃っています。

module.exports = [
  {
    type: "list",
    choices: ["atoms", "molecules", "organisms", "templates", "pages"],
    name: "atomicDirectory",
    message: "What's atomic directory?"
  },
  {
    type: "input",
    name: "componentName",
    message: "What's component file name?"
  }
];

不具合? type: "list"が使えない

prompt.jstype: "list"を使いたかったのですが、choicesを設定しても選択肢が出ませんでした。不具合なのかわからないですが、とりあえずissueだけ立てておきました。誰か反応してくれることを期待しています。

type: "list" in prompt.js is not working...? #131 | jondot/hygen

パラメータにバリデーションを加える

validate関数を定義すればバリデーションを加えることができます。

...
  {
    type: "input",
    name: "componentName",
    message: "What's component file name?",
    validate: (answer) => {
      if (["atoms", "molecules", "organisms", "templates", "pages"].indexOf(answer) > -1) {
        return true;
      }
    }
  }
...

間違った入力結果は❯ Invalid inputを返してくれます。

? What's atomic directory?("atoms", "molecules", "organisms", "templates", "pages") › aaaaa  

❯ Invalid input

挿入したパラメータをいじる

入力した値をhoge-hogeからHogeHogeのようにキャメルケースに変換したいことがあると思います。そんなときはヘルパー関数を使えます。

使えるchangeCase関数のリストはchange-caseというパッケージにあります。

https://github.com/jondot/hygen#case-changing

---
to: components/<%= name %>/index.jsx
---
import React from 'react'

export const <%= name %> = ({ children }) => (
  <div className="<%= h.changeCase.pascalCase(name) %>">{children}</div>"
)

ヘルパー関数は自分で定義することもできます。設定ファイル.hygen.jsにヘルパー関数を定義します。

module.exports = {
    helpers: {
        myHelper: s => s.toUpperCase()
    }
}

テンプレートではh.myHelperで呼び出せます。

---
to: given/hygen-js/new.md
---
<%= h.myHelper('hello') %>

実行してファイルを生成する

実行するとprompt.jsで設定した質問事項が聞かれるので、入力するとファイルが生成されます。

$ ./node_modules/.bin/hygen components add
✔ What's atomic directory? · atoms
✔ What's component file name? · Hoge

Loaded templates: _templates
       added: src/components/atoms/Hoge.tsx
       added: src/components/atoms/Hoge.stories.tsx

_templatesフォルダを任意の名前にしたい

.hygen.jsという名前の設定ファイルをトップディレクトリに配置できます。.hygen/というフォルダをテンプレートフォルダにしてみます。

module.exports = {
  templates: `${__dirname}/.hygen`
};

ソースコード

こちらにソースコードを置いておきました。

sandbox/hygen at master · SatoshiKawabata/sandbox · GitHub

参考

Hygenでファイル作成を簡単にする - tyankatsu’s blog hygenで簡単につくる対話式コードジェネレータCLI - Qiita

Hygenでファイル作成を簡単にする