😸

Scaffoldを使用して、コンポーネントをワンコマンドで作成する

2022/08/15に公開

コンポーネント作成時のハードル

React 等でコンポーネントを作っていく際、一つのコンポーネントに対して複数のファイルを割り当てるという作り方はそれなりに多いと思います。例えば Next.js+Storybook 環境下で SASS を使用していたと想定して、以下のようなファイル構成を日頃作っているとします。

src/components/Sample01/index.ts
src/components/Sample01/Sample01.tsx
src/components/Sample01/Sample01.stories.tsx
src/components/Sample01/Sample01.module.scss

もしこれを手動で作るとなると、components フォルダに移動してコンポーネント用のフォルダを作り、さらにファイルを一から作るか、どこかからコピペ&名前変更という作業が待っています。結果、新しいコンポーネントを作る事に対して精神的なハードルが上がり、面倒だから機能ごとに切り分けずにまとめてしまおうという、悪魔のささやきが聞こえてくることになります。

これを解決するには共通部分をテンプレート化し、コマンド一発でさっと作れるようにすれば良いのです。

ツールを用意

この辺りの処理を簡単に出来るようにするためのツールを用意しました。

https://www.npmjs.com/package/@node-libraries/scaffold

インストールは
yarn -D @node-libraries/scaffold
となります

コマンドラインから使う場合(グローバルインストールしていない前提)だと、npm runyarn で起動してください
yarn scaffold

使い方

テンプレートの準備

テンプレート用のフォルダを作成し、その中に必要な設定を書き込みます。
テンプレート用のファイル名は、拡張子を.templateにする必要があります。わざわざそうしている理由は、開発環境のオートフォーマットで体裁が崩れるのを防ぐためです。
ファイル名なテキストの中身は以下の文字列が置換されます。この名前の部分はコマンド実行時に決定します。

{{{NAME}}} -> ComponentName
{{{PATH}}} -> ComponentPath

  • templates/index.tsx.template
export * from "./{{{NAME}}}";
  • templates/{{{NAME}}}.module.scss.template
.root {
}
  • templates/{{{NAME}}}.tsx.template
import React, { FC } from 'react'
import styled from './{{{NAME}}}.module.scss'

interface Props {}

/**
 * {{{NAME}}}
 *
 * @param {Props} { }
 */
export const {{{NAME}}}: FC<Props> = ({}) => {
  return <div className={styled.root}>Sample</div>
}
  • templates/{{{NAME}}}.tsx.template
import React from 'react'
import { {{{NAME}}} } from '.'

const StoryInfo = {
  title: 'Components/{{{PATH}}}{{{NAME}}}',
  component: {{{NAME}}}
}
export default StoryInfo

export const Primary = (args: Parameters<typeof {{{NAME}}}>[0]) => (
  <>
    <{{{NAME}}} {...args}></{{{NAME}}}>
  </>
)
Primary.args = {} as Parameters<typeof {{{NAME}}}>[0]

Primary.parameters = {}

コマンド

  • ./templates からテンプレートを読み込み ./src/components/Samples/Sample01 にコンポーネントを作成
scaffold create -t templates -o src/components Samples/Sample01
  • 省略すると-t./templates-o./src/componentsがデフォルト
scaffold create Samples/Sample01

Scaffold の出力結果

  • src/components/Samples/Sample01/index.tsx
export * from "./Sample01";
  • src/components/Samples/Sample01/Sample01.module.scss
.root {
}
  • src/components/Samples/Sample01/Sample01.stories.tsx
import React from "react";
import { Sample01 } from ".";

const StoryInfo = {
  title: "Components/Samples/Sample01",
  component: Sample01,
};
export default StoryInfo;

export const Primary = (args: Parameters<typeof Sample01>[0]) => (
  <>
    <Sample01 {...args}></Sample01>
  </>
);
Primary.args = {} as Parameters<typeof Sample01>[0];

Primary.parameters = {};
  • src/components/Samples/Sample01/Sample01.tsx
import React, { FC } from "react";
import styled from "./Sample01.module.scss";

interface Props {}

/**
 * Sample01
 *
 * @param {Props} { }
 */
export const Sample01: FC<Props> = ({}) => {
  return <div className={styled.root}>テスト</div>;
};

package.json でコマンドを簡略化

{
  "scripts": { "sf": "scaffold create -t テンプレートフォルダ -o 出力フォルダ" }
}

というようにしておくと、

yarn sf コンポーネント名

という形で、オプションを簡略化できます。

まとめ

Scaffold があるだけで新しいコンポーネントを作る精神的なハードルは一気に下がり、開発速度の上昇にも繋がります。また、チーム内のコンポーネントの作り方のバラツキを押さえる効果もあります。導入すれば開発効率は確実に上がります。客の作業を自動化する前に、自分の作業を自動化することが重要です。

ちなみに今回作成したツールは nodejs の汎用プログラムなので、用途別にテンプレートさえ作成すれば様々なライブラリで使用できます。

GitHubで編集を提案

Discussion