目次
はじめに
概要
Next.js+Tailwind CSS+Storybookを使って、コンポーネントベースのフロントエンド開発に挑戦しました。
下記の順番で進めていきます。
- 環境構築
- Storybookで管理しながらコンポーネントを作成
- APIの呼び出し
- コンポーネントを組み合わせてレイアウト構築
完成図
宝くじ抽選アプリを作っていきます。
開発環境
私はWSL2で作業しました。
node.jsとnpmのバージョンは以下のとおりです。
1 2 3 4 |
$ node -v v23.2.0 $ npm -v 10.9.0 |
環境構築
Next.js+TypeScript+Tailwind CSSの用意
Next.jsアプリを作る
・アプリを作りたい場所で下記を実行
・今回はTypeScriptを使いたいので--ts
を指定
1 |
$ npx create-next-app@latest my-next-app --ts |
・コンソールで下記を質問されるのでそれぞれ選択+Enter
・2番目の「Tailwind CSS?」は必ずYes
1 2 3 4 5 6 |
✔ Would you like to use ESLint? … Yes ✔ Would you like to use Tailwind CSS? … Yes ✔ Would you like your code inside a `src/` directory? … Yes ✔ Would you like to use App Router? (recommended) … Yes ✔ Would you like to use Turbopack for next dev? … No ✔ Would you like to customize the import alias (@/* by default)? … No |
・追加で質問される場合もYesを選択
1 2 3 |
Need to install the following packages: create-next-app@15.0.3 Ok to proceed? (y) y |
・pacakgeのインストールなど辛抱強く待ちます…
Next.jsアプリを起動、動作確認
・完了後、プロジェクト名のフォルダへ移動(package.jsonがあるところ)
・下記を実行して起動
1 |
$ npm run dev |
・http://localhost:3000
へアクセス
・page.tsxを適当に修正し、リアルタイム更新されることを確認
・今回は下記のようにTailwind CSSのクラス名を追加してみました
1 |
<li className="text-red-500">Save and see your changes instantly.</li> |
・変更が反映されたのでNext.jsとTailwind CSSの用意完了!
リアルタイム更新されないとき
・package.jsonにあるscriptのdevに「WATCHPACK_POLLING=true」を追記
・Next.jsのファイル変更を検知が、WSL2では期待通りに動作しないことがあるようです
・ポーリング方式(一定間隔でファイル変更をチェックする)にすることで、確実に変更検知するようになりました
1 |
"dev": "WATCHPACK_POLLING=true next dev", |
Storybookの用意
Storybookをインストール
・package.jsonがある場所に移動
・Storybookをインストール
1 |
$ npx storybook init |
・下記のように質問されたらYes
1 2 3 |
Need to install the following packages: storybook@8.5.1 Ok to proceed? (y) |
・こちらもmpacakgeのインストールなど辛抱強く待つ…
Storybookを起動、動作確認
・初回は自動起動しました
・次回以降は下記で起動させればOK
1 |
$ yarn storybook |
・UIを適当に操作してみます
・Buttonコンポーネントが用意してありました
・Storybookの用意完了!
リアルタイム更新されないとき
・package.jsonにあるscriptのstorybookに「WATCHPACK_POLLING=true」を追記
1 |
"storybook": "WATCHPACK_POLLING=true storybook dev -p 6006" |
フォルダ構成を整える
CSS置き場
・Next.jsアプリを作成すると、デフォルトで/src/app/globals.css
が生成されます
・今回は/src/css
を用意し、ここにglobals.css
を置くことにします
image置き場
・Next.jsアプリを作成すると、デフォルトで/public
に画像が直接置かれています
・今回は/public/images
を作成し、ここに画像を置くことにします
・フォントを置く場合も、/public/fonts
を用意すれば良さそうです
コンポーネント置き場
・Storybookをインストールすると、デフォルトで/src/stories
にサンプルのコンポーネントが生成されます
・今回は /src/components
を用意し、ここに作成したコンポーネントを置くことにします
・コンポーネントごとに更にフォルダを作成し、.tsx
と.stories.tsx
を配置します
ページの用意
Next.jsだとApp Routerを使う場合が多いので、宝くじ抽選画面として/src/app/lottery
を作成しました。
上記を踏まえて、以下の構成になりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
my-next-app ├── public | └── images | └── logo.svg ├── src | ├── app | | ├── lottery | | | └── page.tsx | | ├── layout.tsx | | └── page.tsx | ├── css | | └── global.css | └── components | └── button | ├── button.css (これは後で消す) | ├── Button.tsx | └── Button.stories.tsx └── package.json |
StorybookにTailwind CSSを適用させる
適用確認のための準備
・サンプルのButtonコンポーネントを↑のように配置しておきます
・その他のサンプルはすべて削除します
・ボタンラベル部分を<span>
で囲み、Tailwind CSSのクラス名を記載
1 |
<span className='text-red-500'>{label}</span> |
・/src/app/lottery/page.tsx
を作成し、宝くじ抽選画面を用意
・先ほど用意したButtonコンポーネントを呼び出します
1 2 3 4 5 6 7 8 9 10 11 |
"use client"; import { Button } from "../../comopnents/button/Button"; export default function Home() { return ( <div className="p-5"> <Button primary={false} label="宝くじ抽選ページで呼び出した" /> </div> ); } |
適用確認
・npm run dev
でアプリを起動
・http://localhost:3000/lottery
へアクセスすると、Buttonコンポーネントのラベルが赤色になっていました↓
しかし、Storybookでは赤色になっていません…!↓
適用させる
global.css
の先頭に「Tailwindを使う」宣言があるので、Storybook側でもこれを読み込む必要があるようです。
1 2 3 |
@tailwind base; @tailwind components; @tailwind utilities; |
・/.storybook/preview.ts
に下記を追記
1 |
import "../src/css/globals.css"; |
・Tailwindsに適用範囲を追加(今回のようにsrc/componentsにコンポーネントを作成する場合は不要)
1 2 3 4 5 6 7 8 |
import type { Config } from "tailwindcss"; export default { content: [ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}", ], |
・Storybookを起動しなおして確認すると、アプリ側と同じく赤色になっている=Tailwind CSSが適用されました!
Tailwind CSSが反映されない場合
・/postcss.config.mjs
を/postcss.config.js
に変更、中身を下記に変更
1 2 3 4 5 |
module.exports = { plugins: { tailwindcss: {}, }, }; |
おわりに
環境構築は以上です。
次回はコンポーネントを作っていきます。