Vite × React × TanStack Router で始める快適フロント開発環境の構築

# はじめに
先日、研究室の皆さんと[技育CAMPハッカソン](https://talent.supporterz.jp/events/6f769c37-5709-4ddc-804e-4c4ff38d2112/)に参加してきました。
ハッカソンで開発した成果物については、すでに同輩が記事を作成してくれています。
成果物の詳細につきましては、以下の記事をご覧ください。

https://qiita.com/aridome222/items/daf4465faffa608cb202

本記事のバックエンド版にあたるものについては、これまたすでに先輩が記事を作成してくださりました。Goが気になる方はこちらもご覧ください。

https://qiita.com/KakinokiKanta/items/b943b8aefc13d055aa85

# テンプレートリポジトリの公開

今回かなり丁寧に書いていったためか、全体で 800 行ほどになってしまいました。
そこで、今回はこの記事を作るにあたって作成した、環境作成が終わったリポジトリをテンプレートとして公開することにしました。
このページを参考に1から環境構築してもよいですが、面倒な方は以下のリンクからフォークして使ってあげてください。
今思えば、本当に快適な環境構築は、すでに環境構築が終わったものを渡されることなのかもしれない……と。

https://github.com/YKhm20020/React-project-template

# 想定する読者

- Webフロントの開発は未経験である
- キャッチアップは経験しているが、開発着手から関わるのははじめて
- Next.js は触ったことがあるが React は使ったことがない

とにかく快適に、悩むことを極力減らして、汎用的に使えるフロントエンドの環境構築ができることを目的として本記事の作成に至りました。
なので、各技術の詳細等については省略し、簡略化した説明のみを補足する形で紹介していきます。

# 環境
macOS 15.0 Sequoia

一部 brew コマンドでツールをインストールしていますが、Windows や Linux の方は、別途公式ドキュメントに従って準備をお願いいたします。
公式のサイトからNode.jsのZIPファイルのダウンロードなどが必要だと思われます。
Node.js 以外については、動きは変わらないと思われます。

# 主な使用技術

- Node.js
- Vite
- React
- tailwindcss
- TanStack Router
- Storybook

## Node.js
[Node.js](https://nodejs.org/en)は、Javascriptランタイムのひとつです。ランタイムとは、開発環境全般のことを指します。
他にもBunや、最近話題のDenoもありますね。
今回は安定して使うことができ、ドキュメントも多いNode.jsでストレートに。

## Vite
[Vite](https://ja.vitejs.dev/)は、Javascriptビルドツールのひとつです。発音は ヴィート らしいですが、ヴィットなどの表記揺れもあるらしい。私はヴィート派ですが、そもそも相手に伝わればなんでもよし派。
他には、webpack や Turbopack などが有名でしょうか。Next.jsを触ったことがある方は聞いたことがあるかもしれません。
他のビルドツールと比較して、かなり高速にビルドできます。具体的には、今回の成果物で測ったところ、 650ms 前後でした。Viteを使わない場合、開発初期でほぼファイルがないにもかかわらず体感で3秒前後かかっていたので、どれくらい高速かわかると思います。
公式ドキュメントも日本語に対応しており、日本人にとって理解しやすいのもありがたいところでしょう。
快適フロント開発環境の「快適」はViteによるものが大きいです。なにせサーバーを立てる度にビルドが必要ですから、ここがすぐに起動すると嬉しい。


## React
[React](https://ja.react.dev/)は、Javascriptライブラリのひとつです。今回は言語と大雑把に言って差し支えはないでしょう。
TypeScriptをJSXという記法で書いていきます。TypeScriptが主流となった今、Javascriptをそのまま書くことはあまりないでしょう。差し障るほどの違いもないため、TypeScriptで型をつけて開発して未然にバグを防ぐ方がよいという考えが一般的ですね。


## tailwindcss
[tailwindcss](https://tailwindcss.com/docs/installation)は、CSSライブラリのひとつです。
ユーティリティクラスというあらかじめ決められたクラスでデザインを構成しようという設計思想に基づいています。
最近議論に上がりがちなtailwindですが、僕は好きなのでCSSはtailwindを採用しています。
tailwindを準備する箇所を他のCSSに置き換えれば、問題なく環境構築できるはずです。


## TanStack Router
[TanStack Router](https://tanstack.com/router/latest)は、ルーティングライブラリのひとつです。
Next.jsの開発経験がある方は、Pages Router, App Router にかかわらず、ファイルを作ればその名前で勝手に実際のURLが構成されていたはずです。快適にページ遷移を実現していることでしょうが、Reactは標準でその機能(ファイルベースルーティング)はありません。
そこで、TanStack Router を採用し、ファイルベースでのルーティングでファイル名とルーティングを一致させつつ、型安全にしてしまおうというものです。
環境構築段階では、ルーティングがファイルベースであるという一点で快適さを生んでいます。

## Storybook
[Storybook](https://storybook.js.org/)は、UIカタログツールのひとつです。
Webページを構成する部品（ボタン、ヘッダーなど）をそれぞれで確認できます。
UIカタログという性質から、開発段階での確認(スモークテスト)として使うことが多いですが、最近ではVitestへの対応など、テスト関連のこともできます。
環境構築では影響がありませんが、実際にコードを書き始めてから恩恵があるものです。せっかくなのでこれを入れるところまで書きます。


# 環境構築
さて、ここから本題の環境構築です。使用技術で紹介した順に入れていきます。


## Node.js の導入
Node.js をインストールします。Macでは homebrew を用いて、nodebrew をインストールして Node.js のバージョンを楽に切り替えられる方が後々困らないでしょうし、その方向で。
homebrew についての解説等は割愛させていただきます。

```sh
brew install nodebrew
```

インストールしたら、.zshrc というファイルを編集してパスを通します。シェルの再起動も忘れずに。

```sh
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc
source ~/.zshrc
```

以下のコマンドで Node.js の安定版をインストールします。最新版でなくて構いません。必要になればまたそのときにダウンロードしましょう。

```sh
nodebrew install stable
```

インストールが完了したら、`nodebrew ls`というコマンドでインストール済みのバージョンの Node.js を確認しましょう。

```sh
nodebrew ls
v20.8.0
v22.2.0
v22.8.0

current: v22.8.0
```

バージョンを切り替えたい場合は、`nodebrew use`コマンドで切り替えられます。

```sh
nodebrew use v20.8.0

use v20.8.0
```

ここで Node.js の準備は完了です。これとセットで、npm のインストールも行われます。
npm は node package manager の略で、必要なパッケージの管理を行ってくれます。tailwindcss や storybook などは、この npm を使ってインストールします。
pnpm など他のパッケージマネージャーもありますが、今回は標準の npm でいきます。

ここまでできたら、バージョン確認のコマンドでそれぞれをインストールできているかを確認して Node.js の導入完了です。


```sh
node -v 
v20.80
```

```sh
npm -v
10.8.3
```

npm コマンドが見つからないというエラーが出る場合は、以下のコマンドで npm を別にインストールしましょう。

```sh
npm install -g npm
```


## Vite の導入

Vite の導入に入ります。ひとつ前に紹介した Node.js, npm はインストールできている前提で進めていきます。
プロジェクトを作りたいディレクトリへ移動して、以下のコマンドで viteを導入します。

```sh
npm create vite@latest
```

実行すると、以下のような画面になります。vite-project の箇所は薄い灰色となっていて、ユーザーが決められます。ここでは、react-project-template としましょう。

```sh
npm create vite@latest
> npx
> create-vite

? Project name: › react-project-template
```

すると、以下のような画面になります。Vue や React の文字がカラフルになっています。今回は React での環境構築なので、上から3番目で薄紫色の React を選択。マウスではなく、矢印キーで移動して、エンターキーで決定します。

```sh
✔ Project name: … react-project-template
? Select a framework: › - Use arrow-keys. Return to submit.
❯   Vanilla
    Vue
    React
    Preact
    Lit
    Svelte
    Solid
    Qwik
    Others
```

Reactを選択すると、次は下のような画面になります。ここでは、上から2番目の TypeScript + SWC を選びましょう。

SWC（Speedy Web Compiler）は、Javascript や TypeScript のコンパイル(トランスパイル) ツールです。ビルドが高速である理由のひとつでもあるので、ぜひ SWC を選びましょう。

```sh
✔ Project name: … react-project-template
✔ Select a framework: › React
? Select a variant: › - Use arrow-keys. Return to submit.
❯   TypeScript
    TypeScript + SWC
    JavaScript
    JavaScript + SWC
    Remix ↗
```

ここまで行くとこの画面に。

```sh
✔ Project name: … react-project-template
✔ Select a framework: › React
✔ Select a variant: › TypeScript + SWC

Scaffolding project in <ここはそれぞれのディレクトリ構成で変化>...

Done. Now run:

  cd react-project-template
  npm install
  npm run dev
```

さて、Done. という文字がありますね。これでViteの導入終了です。
なんと高速なのはビルドだけじゃないんですね。初めて使ったときは自分も驚きました。あまりに手軽すぎて。
さらにいうと、なんと React の導入も実はほぼ終わっています。React導入で書くことがなくなってしまうので、その後に行うべきコマンドを書こうと思います。


## React の導入 (動作確認まで)
先述した通り、React の導入は Vite の導入と同時にほとんどが終了しています。
なので、Vite を導入後、必要なコマンドやサーバーが立てられるかの確認までをここで書こうと思います。

```sh
✔ Project name: … react-project-template
✔ Select a framework: › React
✔ Select a variant: › TypeScript + SWC

Scaffolding project in <ここはそれぞれのディレクトリ構成で変化>...

Done. Now run:

  cd react-project-template
  npm install
  npm run dev
```

これは、Vite の導入が終わった段階での画面です。
Done. Now run: 以降にあるコマンドを実行していくことになります。

ディレクトリ移動後、`npm install`コマンドで、package-lock.json というファイルに従って、必要なパッケージをインストールします。以下の画面が表示され、node_modules というフォルダができていれば完了です。

```sh
cd react-project-template
npm install
```

```sh
npm install

added 144 packages, and audited 145 packages in 15s

38 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

さて、ここまでできれば React の導入が完了できています。
`npm run dev`コマンドで、サンプルのページを開けるか試してみましょう。

```sh
npm run dev
```

```sh
npm run dev
> react-project-template@0.0.0 dev
> vite


  VITE v5.4.8  ready in 308 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
```

かなり高速ですね。308ms。開発開始時点だと約半分の時間でビルドできるみたいです。
この表示のまま、http://localhost:5173/ にアクセスしましょう。
以下にある画像のページに遷移できていれば成功です。右にある React のマークがくるくるしています。
おそらく、Vite 導入からここまでで速ければ30秒くらいでいけちゃいます。
これをもって、React の導入完了とします。

![スクリーンショット 2024-10-01 20.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/61a3a54f-c4d2-1605-28df-22ceaae1f701.png)


## tailwindcss の導入
ここから、tailwindcss の導入に入ります。サーバーを起動している場合は、Ctrl + C で一旦閉じましょう。

`npm install <パッケージ名>`で、指定パッケージをインストールします。複数指定すれば、同時にそれらをインストールできます。npm でインストールする、と Node.js 導入で書いたのはここのことです。
ここでは、[公式ドキュメント](https://tailwindcss.com/docs/guides/vite)に従ってインストールします。幸いなことに、Vite のプロジェクトでインストールする際のドキュメントが揃っています。感謝感謝🙏
--save-dev というオプションでインストールしているのと同じ意味の -D オプション。これは、開発環境にてインストールするパッケージであると明示することを指します。

```sh
npm install -D tailwindcss postcss autoprefixer
```

```sh
npm install -D tailwindcss postcss autoprefixer

added 87 packages, and audited 234 packages in 6s

65 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

インストールが完了したら、以下のコマンドでコンフィグファイルの雛形を作ってもらいます。-p のオプションは、途中でインストールした postcss のコンフィグファイルの雛形も同時に作ることを意味しています。

```sh
npx tailwindcss init -p
```

```sh
npx tailwindcss init -p

Created Tailwind CSS config file: tailwind.config.js
Created PostCSS config file: postcss.config.js
```

コマンド実行後、tailwind.config.js というファイルと、postcss.config.js というファイルの2つのファイルが自動で作成されます。
できあがったコンフィグファイル (tailwind.config.js) の無編集の状態がこちら。

```tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: [],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

こちらを、以下のように変更します。content のブラケットに追記があります。

```tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: [
+    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

これは、tailwindcss を適用する範囲を設定しています。この記述が意味するのは、「scr より下にある全てのディレクトリにおける、js, ts, jsx, tsx の拡張子のファイルに tailwindcss を適用する」になります。

ちなみに、postcss.config.js の無編集状態がこちら。このファイルについては、特に変更すべき箇所はありません。

```postcss.config.js
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```

続いて、tailwindcss をインポートする .css のファイルを作成します。私は Next.js に慣れていたので、成果物では styles というディレクトリを作り、その下に globals.css というファイルを作成しました。
src の下に、App.css というファイルがあり、そのファイルの中身を以下に示すものに書き換えるのもよいでしょう。

作成した (書き換えた) .css に、以下の3行を書き込みましょう。あとは、tailwindcss を使うファイルで .css をインポートすればよいです。
トップページ (今回でいうと、src の下にある App.tsx) でインポートすると、その配下のページやコンポーネントにも tailwindcss が効くので、いちいちファイルを作る度にインポートする必要がありません。

```globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

さて、ここまでできたら動作確認です。
src/App.tsx を以下のように書き換えましょう。サンプルページの出来がいいので躊躇してしまいますが、思い切って破壊の心を持ちましょう。~~どうせ変更します。~~

```App.tsx
// CSS のインポートは各自作成・変更したものに合わせる
import '../styles/globals.css'

function App() {

  return (
    <div className='min-h-screen w-screen flex justify-center items-center'>
      <div className="flex flex-col justify-center items-center">
        <h1 className='text-3xl font-bold underline'>Hello world!</h1>
      </div>
    </div>
  );
}

export default App
```

`npm run dev`コマンドで、http://localhost:5173/ を開いて、以下のようなページに変わっていたら導入完了です。

![スクリーンショット 2024-10-01 22.10.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/09ba9097-740f-5269-0297-663772b31990.png)


## TanStack Router の導入
ここから、TanStack Router の導入になります。公式ドキュメントは英語のみですが、手順に従えば自然に導入できます。
成果物の作成にあたり、技術的な挑戦として今回はじめて扱うことにしました。
勝手に詰まっていたのですが、うまくいくコツは破壊の心をもつことです。

以下のコマンドで TanStack Router をインストールしましょう。

```sh
npm install @tanstack/react-router
npm install -D @tanstack/router-plugin @tanstack/router-devtools
```

インストールが終わったら、vite.config.ts というルートにあるファイルを書き換えていきます。このファイルは Vite の導入が終わった時点で存在しているはずです。書き換える前の状態がこちら。

```vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})
```

この vite.config.ts を、下のように書き換えましょう。

```vite.config.ts
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { TanStackRouterVite } from '@tanstack/router-plugin/vite' // 追加！

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    TanStackRouterVite(), // 追加！
],
  optimizeDeps: {
    force: true,
	exclude: ['node_modules/.cache/storybook']
  },
})
```

optimizeDeps の箇所が増えていますが、これはあとに入れる Storybook のためです。先に書いておきました。

さて、次は src の下に routes というディレクトリを作成しましょう。

```sh
mkdir src/routes
```

作成した routes ディレクトリの下に、__root.tsx というファイルを作成しましょう。ディレクトリが routes で、ファイルが root です。間違っていません。

```sh
touch src/routes/__root.tsx
```

作成した __root.tsx に、以下のように書き込みましょう。

```__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router';
// import { TanStackRouterDevtools } from '@tanstack/router-devtools';

export const Route = createRootRoute({
	component: () => (
		<>
			<Outlet />
			{/* <TanStackRouterDevtools /> */}
		</>
	),
});
```

TanStackRouterDevtools は、名前からもわかるように、開発者ツールになります。全ページに小さなコンポーネントが映ります。使いたい方はコメントアウトを外してください。デプロイする際にも表示されるので、その際は、このようにコメントアウトを忘れずに。

次は、同じく routes ディレクトリに、index.lazy.tsx ファイルを作成しましょう。

```sh
touch src/routes/index.lazy.tsx
```

中は以下のように書きます。

```index.lazy.tsx
import { createLazyFileRoute } from '@tanstack/react-router';
import App from '../App';

export const Route = createLazyFileRoute('/')({
	component: () => <App />,
});
```

コードの解説ですが、createLazyFileRoute の中がURLのパスになります。なので、about という名前のパスでページを作成したいときは、'/' を '/about' にするとよいです。
component: () => <App />, については、遷移先のページで表示するコンポーネントになります。各コンポーネントをまとめたページをインポートして、それをそのまま入れるのが賢いでしょう。
もちろん、ここに直接書き込むのもよいです。公式ドキュメントもそうなっていましたが、pages というディレクトリを作ってそこでページをまとめた方が楽だと思っている派なので、この方法で。
routes に直接ページの中身を書きたい人は、ここに書くとよいです。

なので、このコードは 「'/' というパスでは App コンポーネントを表示する」という意味になります。

ということで、例に出した About ページを簡単に作って、初期ページから About ページへ、'/about' というリンクで遷移できるようにしてみましょう。
まずは、遷移先の About ページを作成します。pages というディレクトリを src 配下に作成し、さらにその中に About.tsx という名前のファイルを作成しましょう。

```sh
mkdir src/pages
touch src/pages/About.tsx
```

中はなんでもよいのですが、App.tsx の中身を借りて、文字だけ変える形で。元のページへ戻るボタンはつけない方がページが変わったことがわかりやすいので入れていません。

```About.tsx
import type React from 'react';

export const About: React.FC = () => {
    return (
        <div className='min-h-screen w-screen flex justify-center items-center'>
            <div className="flex flex-col justify-center items-center">
                <h1 className='text-3xl font-bold underline'>About Page</h1>
            </div>
        </div>
    );
}
```

次は、トップページである App.tsx の編集に移ります。
Hello, world! の文字の下に、青いボタンを作成して、そのボタンを押すと About ページへと遷移するようにしてみましょう。
TanStack Router の Link コンポーネントを用いて、to='' のところにパスを書きましょう。今回は '/about' になります。

```App.tsx
import '../styles/globals.css'
import { Link } from '@tanstack/react-router';

function App() {

  return (
    <div className='min-h-screen w-screen flex justify-center items-center'>
      <div className="flex flex-col justify-center items-center">
        <h1 className='text-3xl font-bold underline'>Hello world!</h1>
        <Link to='/about' className='bg-blue-500 text-white p-4 mt-4'>To About</Link>
      </div>
    </div>
  );
}

export default App
```

次は、ルーティングの設定を行うファイルを作成します。routes ディレクトリの下に、about.lazy.tsx というファイルを作成しましょう。

```sh
touch src/routes/about.lazy.tsx
```

ちなみに、◯◯.lazy.tsx というファイルをルーティングにあたり作成していますが、この lazy については記述しなくてもルーティングを設定できます。
ではこの lazy とはなにかというと、**遅延ロード**であることを指します。

TanStack Router には、Code Split という機能が備わっており、ルーティングをロードする方式として、Critical Route と Lazy Route に分かれます。それぞれ初回ロード時に読み込むコードと、必要となった際に読み込むコードです。
Lazy Route のルーティングによって、全てのルーティングが初回ロード時に読み込まれることがなくなり、初回ロードまでにかかる時間が短縮できます。

Lazy Router の説明をしたところで、about.lazy.tsx の中は、このように書きましょう。

```about.lazy.tsx
import { createLazyFileRoute } from '@tanstack/react-router';
import { About } from '../pages/About';

export const Route = createLazyFileRoute('/about')({
    component: () => <About />,
});
```

さて、ここでわかったと思いますが、index.lazy.tsx と書き方がほぼ同じです。違うところは、About コンポーネントをインポートして呼び出しているところですね。
ページの中身を直接書き込まず、pages ディレクトリに置いたページのコンポーネントをまるまるインポートする書き方にすることで、routes ディレクトリのファイルがほぼコピペできるようになります。
私はこの書き方の方が修正するところを最小限に使い回せるので好きです。

ここでさらに、src 下の main.tsx を[公式ドキュメント](https://tanstack.com/router/latest/docs/framework/react/quick-start)にしたがって編集しつつ、tailwindcss 導入編で作成したCSSファイルをインポートします。

```main.tsx
import { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider, createRouter } from '@tanstack/react-router';
import './../styles/globals.css'; // 忘れずに！

// Import the generated route tree
import { routeTree } from './routeTree.gen';

// Create a new router instance
const router = createRouter({ routeTree });

// Register the router instance for type safety
declare module '@tanstack/react-router' {
	interface Register {
		router: typeof router;
	}
}

// Render the app
const rootElement = document.getElementById('root')!;
if (!rootElement.innerHTML) {
	const root = ReactDOM.createRoot(rootElement);
	root.render(
		<StrictMode>
			<RouterProvider router={router} />
		</StrictMode>,
	);
}
```

これは、TanStack Router で遷移した先のページ限定で、リロードすると tailwidncss が全部効かなくなるという問題を解決するために行っています。
ページ遷移後限定で起こったことを考慮すると、原因はおそらく、routes 配下のページでは tailwindcss をインポートせず、かつ各コンポーネントでもインポートしておらず、App.tsx でのみインポートをしていたためであると推測しました。
なので、main.tsx で TanStack Router で遷移するページも含めて tailwindcss を適用するようにしています。

ここまでできて、初期ページがこのように表示されていれば TanStack Router の導入が完了です。

![スクリーンショット 2024-10-02 19.18.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/d7d0bf39-4341-7c59-ef58-02fe8dcecb61.png)

ちなみに About ページはこんな感じ。初期ページの To About という青いボタンを押すと遷移できることを確認できるとよいですね。

![スクリーンショット 2024-10-02 19.18.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/aece62b3-a685-474f-2140-47ba41f31988.png)

ここまでたどり着くと、routeTree.gen.ts だったり、tsconfig.app.tsbuildinfo, tsconfig.node.tsbuildinfo というファイルが勝手に増えていることに気づくと思います。
TanStack Router は routes ディレクトリでどのページへどのリンクで飛ぶのかを React が理解できるように書いたファイルを自動で作ってくれるんですね。ファイルベースルーティングのありがたみを感じながら、作ったページのコードと同時にコミット・プッシュしましょう。感謝感謝。

## Storybook の導入
ここから、Storybook の導入に入ります。最初は npm install ではなく、以下のコマンドで導入をはじめます。質問には y を入力してエンター。

```sh
npx storybook@latest init
Need to install the following packages:
storybook@8.3.4
Ok to proceed? (y) 
```

色々とインストールされ、ログも多く出てきますが、下のような赤い四角で囲まれた文章が表示されていればインストール成功です。

```sh
╭──────────────────────────────────────────────────────────────────────────────╮
│                                                                              │
│   Storybook was successfully installed in your project! 🎉                   │
│   To run Storybook manually, run npm run storybook. CTRL+C to stop.          │
│                                                                              │
│   Wanna know more about Storybook? Check out https://storybook.js.org/       │
│   Having trouble or want to chat? Join us at https://discord.gg/storybook/   │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯
```

インストールが終わると、勝手に Storybook のサーバーが立ち上がり、ページも開いてくれるはず。優しい。
もし表示されなければ、以下のコマンドで Storybook のサーバーを動かしましょう。

```sh
npm run storybook
```

サーバーを動かしたまま http://localhost:6006/ から下のような画面のページが開ければ導入完了です。

![スクリーンショット 2024-10-02 13.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/2cc254b6-e9cd-85ba-9719-703e0f733286.png)

しかしこのままでは、Vite + TanStack Router 環境ではドキュメント関連がうまく表示できないようです。Storybook のページで、Configure your project のページを見ると、以下のように真っ白のままです。本来は、ここに Storybook の使い方が載っています。

![スクリーンショット 2024-10-02 17.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/50e02204-dc96-54f0-fad6-1966b548ae88.png)

これを解消するために、.storybook というフォルダの中にある preview.ts というファイルを previes.tsx という名前に書き換え、中身を書き換える必要があります。

書き換え前の preview.ts ファイルがこちら。

```preview.ts
import type { Preview } from "@storybook/react";

const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
};

export default preview;
```

これを、preview.tsx の名前に書き換え、中身も変更したものがこちら。ファイル名を .ts から .tsx に書き換えるのを忘れずに。そうでないと、真っ白どころかエラーのページが出ます。

```preview.tsx
import type { Preview } from '@storybook/react';
import { RouterProvider, createMemoryHistory, createRootRoute, createRouter } from '@tanstack/react-router';
import '../styles/globals.css';

const preview: Preview = {
  decorators: [
    (Story) => {
      return <RouterProvider router={
        createRouter({
          history: createMemoryHistory(),
          routeTree: createRootRoute({
            component: Story
          })
        })
      } />
    }
  ]
};

export default preview
```

TanStack Router の必要なモジュールをインポートしつつ、tailwind 導入編で作成した CSS ファイルもインポートしています。
これは、Storybook で tailwindcss を用いたコンポーネントを表示する際に、tailwindcss が効いていないという問題を解消するためです。

さて、次は同じく .storybook フォルダの中にある main.ts も書き換えていきます。こちらは、名前を変更する必要はありません。
変更前がこちら。

```main.ts
import type { StorybookConfig } from "@storybook/react-vite";

const config: StorybookConfig = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
  addons: [
    "@storybook/addon-onboarding",
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@chromatic-com/storybook",
    "@storybook/addon-interactions",
  ],
  framework: {
    name: "@storybook/react-vite",
    options: {},
  },
};
export default config;
```

これを、必要なパッケージをインストール後、以下のように書き換えましょう。具体的には、cores の中に builders の記述を追加します。

```sh
npm install @storybook/builder-vite --save-dev
```

```main.ts
import type { StorybookConfig } from "@storybook/react-vite";

const config: StorybookConfig = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
  addons: [
    "@storybook/addon-onboarding",
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@chromatic-com/storybook",
    "@storybook/addon-interactions",
  ],
  framework: {
    name: "@storybook/react-vite",
    options: {},
  },
  core: {
    builder: '@storybook/builder-vite', // 追加！
  },
};
export default config;
```

これら2つのファイルを書き換えたら、一度 Ctrl + C でサーバーを落とし、`npm run storybook` でビルドしなおしつつ、サーバーを立て直しましょう。
以下のようにドキュメントが表示されると、晴れて Storybook の導入完了です。

![スクリーンショット 2024-10-02 18.10.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475006/43e21048-5386-7c11-5fe1-a62d1d43baaa.png)

# おわりに
かなり長いページとなってしまいましたが、ここまで読んでくださりありがとうございました。
ここまで丁寧に、かつ長く書いたのは初めてだったので、いい経験になりました。
せっかくプロダクトを作るなら、その前準備に時間をかけるよりも中身のコードを書いていたいですよね。特にハッカソンなど、開発期間が短時間で終わっていまう場合は。

環境構築も快適に、コードを書く最中も快適に。を重視してこの記事を公開しました。
本当は Biome の導入もしたかったのですが、記事がさらに長くなってしまうことと、Biome は発達途中であまり好みではないという意見もあることを考えると、快適からは外れると考えたため、入れていないです。
ちなみに僕は Biome 好き派なので、気になる方はぜひ使ってみてください。


# 参考文献
- [「経験談」初ハッカソンでボロ負けして学んだこと](https://qiita.com/aridome222/items/daf4465faffa608cb202)
- [Docker+PostgreSQL+Go+Airで実現する快適サーバーサイド開発環境構築のすゝめ](https://qiita.com/KakinokiKanta/items/b943b8aefc13d055aa85)

- [Node.js — Run JavaScript Everywhere](https://nodejs.org/en)
- [Vite | 次世代フロントエンドツール](https://ja.vitejs.dev/)
- [React](https://ja.react.dev/)
- [Get Started with Tailwind CSS](https://tailwindcss.com/docs/installation)
- [Quick Start | TanStack Router React Docs](https://tanstack.com/router/latest/docs/framework/react/quick-start)
- [Vite- Storybook](https://storybook.js.org/docs/builders/vite)

- [macにnode.js（npm）をインストールするならnodebrewがおすすめ](https://fromscratch-y.work/blog/programming/mac-nodejs-install/)
- [npm install の --save-dev って何？](https://qiita.com/kohecchi/items/092fcbc490a249a2d05c)
- [TanStack Router（& Query）はSPA開発で求めていたものだった✨【Reactのルーティングとデータ取得】](https://zenn.dev/aishift/articles/ad1744836509dd)