scaffdog でサクッとファイルを作成する

普段の開発で React を使っていると、コンポーネントファイルを作成することが多いですよね。
筆者も最近参入したプロジェクトで大量のコンポーネントを作成しています。
Storybook やテスト用のファイルも作成するので、雛形のファイルを作っておいてそれをコピペして使うようにしていました。
しかしそれもだんだんと面倒になってきたので、scaffolding ツールを使うことにしました。

scaffolding ツールとは

scaffolding ツールとは、テンプレートを基にファイルを生成するツールのことです。
今回紹介する scaffdog の他に、 PlopHygen などがあります。
Hygen は以前使ったことがあり、高機能ですが設定がやや面倒でした。
今回は scaffdog を使ってファイルを作成していきます。

使い方

まずは scaffdog をインストールします。

npm install -D scaffdog

次に、設定ファイルを作成します。
名前を聞かれるので、 component と入力してみます。

$ npx scaffdog init
? Please enter a document name. component

Setup of scaffdog 🐶 is complete!

   .scaffdog/config.js
   .scaffdog/component.md

Now you can do scaffold by running $ scaffdog generate.

Please refer to the following documents and customize it.
https://scaff.dog/docs/templates

すると、 .scaffdog ディレクトリが作成され、その中に config.jscomponent.md が作成されます。

scaffdog では PlopHygen とは違い、マークダウンファイルを使ってテンプレートを作成します。
以下のように component.md を編集してテンプレートを作成します。
テンプレートファイルの記法については こちら を参照してください。

---
name: 'component'
root: 'src'
output: '**/*'
ignore: []
questions:
  name: 'コンポーネント名を入力してください。'
---

# `{{ inputs.name | pascal }}/index.ts`

```ts
export { {{ inputs.name | pascal }} } from './{{ inputs.name | pascal }}'
export type { {{ inputs.name | pascal }}Props } from './{{ inputs.name | pascal }}'

```

# `{{ inputs.name | pascal }}/{{ inputs.name | pascal }}.tsx`

```tsx
import { clsx } from 'clsx'
import React from 'react'

import styles from './{{ inputs.name | pascal }}.module.css'

export type {{ inputs.name | pascal }}Props = {
  className?: string
}

export function {{ inputs.name | pascal }}({ className }: {{ inputs.name | pascal }}Props) {
  return <div className={clsx(styles.root, className)}>{{ inputs.name | pascal }}</div>
}

```

# `{{ inputs.name | pascal }}/{{ inputs.name | pascal }}.module.css`

```css
.root {
}
```

# `{{ inputs.name | pascal }}/{{ inputs.name | pascal }}.test.tsx`

```tsx
import { userEvent } from '@testing-library/user-event'
import React from 'react'

import { render, screen } from '~jest/utils'

import { {{ inputs.name | pascal }} } from './{{ inputs.name | pascal }}'

describe({{ inputs.name | pascal }}.name, () => {
  test('テスト例', async () => {
    render(<{{ inputs.name | pascal }} />)

    const element = screen.getByText('{{ inputs.name | pascal }}')

    const user = userEvent.setup()
    await user.click(element)

    expect(element).not.toBeInTheDocument()
  })
})

```

# `{{ inputs.name | pascal }}/{{ inputs.name | pascal }}.stories.tsx`

```tsx
import { {{ inputs.name | pascal }} } from './{{ inputs.name | pascal }}'

import type { Meta, StoryObj } from '@storybook/react'

const meta: Meta<typeof {{ inputs.name | pascal }}> = {
  component: {{ inputs.name | pascal }},
  args: {},
}

export default meta
type Story = StoryObj<typeof {{ inputs.name | pascal }}>

export const Default: Story = {}

```

{{ inputs.name | pascal }} という変数が使われていますが、これは入力されたコンポーネント名 ( inputs.name )を PascalCase に変換してくれるヘルパー関数です。
その他にもさまざまなヘルパー関数が用意されているので、詳しくは こちら を参照してください。

これで準備完了です!

使ってみる

実際にファイルを作成してみます。 Button というコンポーネントを作成してみます。

$ npx scaffdog generate component
? Please select the output destination directory. src/components
? コンポーネント名を入力してください。 Button

🐶 Generated 6 files!

      src/components/Button/index.ts
      src/components/Button/Button.tsx
      src/components/Button/Button.module.css
      src/components/Button/Button.module.css.d.ts
      src/components/Button/Button.test.tsx
      src/components/Button/Button.stories.tsx

すると、 src/components/Button ディレクトリが作成され、その中にファイルが生成されました。

各ファイルもしっかりと生成されています。

VSCode 拡張機能

プロジェクトが進行すると、ディレクトリの構造が複雑になってきます。そうなってくると、 CLI でディレクトリを指定するのが面倒になってきます。
そこで出てくるのが、 VSCode 拡張機能です。
こちら からインストールできます。
これが使ってみると神機能でした。ディレクトリを右クリックして Run scaffdog in selected folder. を選択することで、ファイルを作成することができます。

まとめ

今回は scaffdog を使ってファイルを作成してみました。
これでファイルの作成が楽になり、開発がさらに捗ること間違いなしです。

外部リンク