Help us understand the problem. What is going on with this article?

hygenで簡単につくる対話式コードジェネレータCLI

More than 1 year has passed since last update.

hygen

Github: https://github.com/jondot/hygen
Docs: http://www.hygen.io/quick-start/

hygen is the simple, fast, and scalable code generator that lives in your project.

hygenはnode.jsベースに、とっても簡単にテンプレートに沿ったファイルの生成CLIをつくることができます。

今回ReactによるUIコンポーネントを新しく作るときに、決まった構造のファイル群が毎回必要なので活用してみました。

npm i hygen -D

生成したいファイル

例えば Button コンポーネントを作成する場合。今回は例としてこんな感じのファイルたちを用意したいです。

/Button
├── Button.stories.tsx
├── Button.test.tsx
├── Button.tsx
├── README.md
├── index.tsx
├── style.css
└── style.css.d.ts

生成テンプレートを用意

生成したい構造に合わせて、次のようなファイルを用意しました。(※ prompt.js は後述)
ちなみにinitコマンドも用意されてます。

./hygen
└── component
    └── add
        ├── README.md.t
        ├── component.stories.tsx.t
        ├── component.test.tsx.t
        ├── component.tsx.t
        ├── index.tsx.t
        ├── prompt.js
        ├── style.css.d.ts.t
        └── style.css.t

拡張子を含めた出力したいファイル名.t でファイルを用意します。

hygenではこのテンプレートファイルのディレクトリ構造が、そのまま実行時のコマンド構造に対応しています。そのため実行するためにnpm scriptを同時に準備できます。

package.json
"scripts": {
  "add": "hygen component add"
},
$ npm run add

そして同時に設定ファイルも用意します。
これは単純にテンプレートを置く場所を指定してるだけです。今回./hygenに作ってみたのでこうしてます。

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

テンプレートを記述

中身はfrontmatter + ejsで書くことになり、CLIから引数を取ってテンプレート内に適用出来ます。
次の例で言うと、<%= name %> にコンポーネント名を出力することが出来ます。

index.tsx.t
---
to: src/<%= name %>/index.tsx
unless_exists: true
---
export * from './<%= name %>';
component.tsx.t
---
to: src/<%= name %>/<%= name %>.tsx
unless_exists: true
---
import * as React from 'react';

interface I<%= name %>Props {
  text?: string;
}

const <%= name %>: React.FC<I<%= name %>Props> = props => {
  const { text } = props;
  return <div>{text}</div>;
};

export { <%= name %>, I<%= name %>Props };

この中身はかなり便利に書くことができるので、是非公式DocsのTemplatesを参照してみてください。

CLIに対話式インターフェースを追加

あとはCLI実行時にコンポーネント名を入力できるようにするだけで完成です。
用意したaddフォルダの中に prompt.js を作成します。

prompt.js
module.exports = [
  {
    message: 'What is the component name?',
    name: 'name',
    type: 'input',
    validate: answer => {
      if (answer !== '') {
        return true;
      }
    },
  },
];

対話式にしたい内容に沿ったobjectを、質問の個数分の配列にして記述しておくだけです。

今回は name という名前の変数を入力したいので、こうなりました。空欄で実行できてしまうと変なファイルが出来てしまうので、validateも適当に用意してます。

実行するとこうなります。

$ npm run add

> hygen component add

? What is the component name? ›

コンポーネント名を入れると一気にファイルが出力されます。

✔ What is the component name? · Button

Loaded templates: hygen
       added: src/Button/Button.stories.tsx
       added: src/Button/Button.test.tsx
       added: src/Button/Button.tsx
       added: src/Button/index.tsx
       added: src/Button/README.md
       added: src/Button/style.css.d.ts
       added: src/Button/style.css

空欄でEnterを押すとvalidateがきいて怒られます。

? What is the component name? ›

❯ Invalid input

ちなみにファイルが被ってると(つまり既に作成済みの名前を誤って入力した時)、気を利かせてスキップしてくれます。

skipped: src/Button/Button.stories.tsx
skipped: src/Button/Button.test.tsx
skipped: src/Button/Button.tsx
skipped: src/Button/index.tsx
skipped: src/Button/README.md
skipped: src/Button/style.css.d.ts
skipped: src/Button/style.css

今回はやりたいことが超単純だったのでこれだけですが、シンプルなわりには柔軟に作れるので他にもいろいろなことに活用できそうな気がします。

公式には Redux, React Native, Express がユースケースとして紹介されてます。

おわり

usagi-f
Frontend Engineer
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした