チームで Plop のコードジェネレーターを使って React コンポーネント作成を楽にする!


こんにちは、Gaji-Labo でフロントエンドをやっている中嶋です。
Gaji-Labo はチームとして顧客のプロダクトに入り、チームとして価値提供を行っている会社です。
今回は「チーム開発」に焦点を当てて、チーム開発でメンバー間のコードの書き方の違いや、経験などでコードの品質や、保守性の低下というのはよく聞く話です。チームで共通の雛形があり、規約やルールに自然と沿うような形で実装できるといいですよね。今回はそのヒントとなりそうな「コードジェネレーター」についてご紹介したいと思います。

コードジェネレーターとは?

事前に構築されたコードを使用してプログラムをより迅速に雛形を構築できるようにするツールです。たとえば、コンポーネントを作りたい時に、特定のプログラムを実行することで、コンポーネントの雛形を簡単に作成することができたりします。

メリット

作業者の手作業を削減できる

まずはなんと言っても、作業者の手作業を減らすことが出来ることです。
特にコンポーネントなどは、内容は違えど基本的に構造は同じになるので、毎回同じように作成していくのもそれなりの負担になります。
コードジェネレーターを使うことによって手作業を削減することができ、本来集中すべき実装に集中することが出来ると思います。

コンポーネントやフォルダ構造を統一しやすくなる

二つ目はコンポーネントのやフォルダの構造を統一しやすくなることです。
コンポーネントを作成したり、何かファイルを作成したりする場合に、どうしても実装など個人差が生まれることはよくあります。
雛形を用意しておくことで、「どう作れば良いのか?」や「何が必要なのか?」を考える必要がなく、作成された雛形をもとに、規約やルールに沿って実装を行なっていくことで統一された構造を作っていくことができると思います。

デメリット

コードジェネレーターを作る工数が必要

もちろんデメリットもあります。
私が思うデメリットはコードジェネレーターを作成する工数を考えなければならない点だと思います。
コードジェネレーター作成ツールとして JavaScript のライブラリで提供されているものがありますが、インストールしただけでは本来の機能を発揮することはできません。
コードジェネレーターは各プロジェクトで使い方や実装方法は様々なので、各プロジェクトでカスタマイズすることで本来の機能を生かすことができます。
この「カスタマイズ」や「工数」を考えなければいけない点が、導入の障壁になる一番の要因かなと思います。

JavaScript で使用できるコードジェネレーター作成ツール

ここまでメリット、デメリットをご紹介してきましたが、 ここからは JavaScript で使用できるコードジェネレーター作成ツールをいくつかご紹介したいと思います。

Plop

Plop は inquire.js でプロンプト部分をテンプレートエンジン Handlebars のテンプレートをもとに新しいファイルを作成するツールです。

Hygen

Hygen については こちら の記事で詳しく書いてあるので詳しい説明は割愛しますが、Hygen は ejs をベースにして新しいファイルを作成するツールです。

scaffdog

scaffdog はマークダウンドリブンで、マークダウンをベースにして新しいファイルを作成するツールです。

ご紹介したものは採用されている技術こそ違いますが、技術面ではそこまで大差はないので、ご自身のプロジェクトや要件にあったものを選択すれば良いと思います。私自身も Hygen をよく使っていましたが、 npm trends でダウンロード数が 1位の Plop が気になっていたので、今回は Plop を使って簡単な実装を行なっていきたいと思います。

Plop のセットアップ

グローバルインストールも出来ますが、今回はプロジェクトにインストールする想定で進めます。

npm install --save-dev plop

package.json にもスクリプトを追記します。

{
    ...,
    "scripts": {
        "generate": "plop"
    },
    ...
}

plopfile を作成します。今回は mjs で作成します。

このファイルでは実際に使用するジェネレーターの設定を記述します。

// plopfile.mjs

export default function (
  /** @type {import('plop').NodePlopAPI} */
  plop
) {
  plop.setGenerator("component", {
    description: '',
    prompts: [],
    actions: [],
  });
}

setGenerator

このメソッドはジェネレーターをセットアップするためのものです。setGenerator で一つのジェネレーターを作ることができます。基本的には setGenerator を使用しておけば問題ないですが、他の plopfile API もあるので興味のある方は見てみてください。

description

ジェネレーターの説明文を書くことができます。

prompts

コマンドライン上でどのような質問を行うかを設定します。

actions

prompts での入力された情報をもとにどのような振る舞いをするのかを定義することができます。

では実際に簡単なジェネレーターを定義してみましょう。Plop や 他のコードジェネレーターはコマンドライン上で対話形式でファイルを作成していくので、今回はコンポーネント名を入力してその回答結果でコンポーネントが作成されるようなものを実装します。

// plopfile.mjs

export default function (
  /** @type {import('plop').NodePlopAPI} */
  plop
) {
  plop.setGenerator("component", {
    description: 'create new component',
    prompts: [
      {
        type: 'input',
        name: 'componentName',
        message: 'What is the component name?:',
      }
    ],
    actions: [
      {
        type: 'add',
        path: 'src/components/{{pascalCase componentName}}/{{kebabCase componentName}}.tsx',
        templateFile: 'plop-templates/Component.tsx.hbs',
      },
    ],
  });
}

prompts には input の他にも list などの type があり、今回は input なのでコマンドライン上に直接入力する形になります。actions には add と指定しているため、新しくファイルを追加するということになります。

最後にテンプレートを作成していきます。テンプレートファイルは Handlebars を用いて作成するため、.hbs という拡張子になります。

// plop-templates/Component.tsx.hbs

import { FC } from 'react';

export const {{pascalCase componentName}}: FC = () => {
  return (
    <div>{{pascalCase componentName}}</div>
  );
};

plopfile や .hbsのファイルでは {{componentName}} とすることで prompts の name の値を参照することが可能です。また pascalCase などが標準でサポートされているので、入力時に意識ぜずともファイル側で変換してくれるのは嬉しいポイントです。

ここまで準備ができたらコマンドを実行してみましょう。

npm run generate

無事にコンポーネントが作成されました。今回は全て紹介することができなかったのですが、 Plop を含むコードジェネレーターにはまだまだたくさんの機能があるので、ぜひご自身で触ってみてください。

チーム開発で使うコードジェネレーター

今回 Plop を通して「コードジェネレーター」についてお話しさせていただきましたが、「とっつきにくそう」というイメージから、少しでも「良さそう、使ってみよう」、と思って頂けるような方が増えていくといいなと思い、ブログにしてみました。コーディング規約や、ルールによって制約を作るということも大事ですが、こういったツールを使って作業者の負担を減らしつつ、規約に沿ったコードが自然に揃うような仕組みづくりも、チーム開発を行なっていく上でとても大切だと思っているので、その一助となれたら嬉しいです。

今後もチーム開発に活かせるような技術発信をしていけたらと思っているので、引き続きよろしくお願いいたします。

Gaji-Labo は Next.js, React, TypeScript 開発の実績と知見があります

フロントエンド開発の専門家である私たちが御社の開発チームに入ることで、バックエンドも含めた全体の開発効率が上がります。

「既存のサイトを Next.js に移行したい」
「人手が足りず信頼できるエンジニアを探している」
「自分たちで手を付けてみたがいまいち上手くいかない」

フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にご相談ください。

オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。

Next.js, React, TypeScript の相談をする!

投稿者 Shota Nakashima

フロントエンドエンジニア。 業界未経験から受託開発、toBサービスの開発経験を経てGaji-Laboに参加。 フロントエンド、バックエンド問わずモダンな技術に興味・関心があります。将来はフロントエンドのエキスパートになりたいと思っています。 プライベートでは5児の父で、イクメンエンジニアを目指して日々奮闘中です。