React+Tailwind CSS+Storybook のプロジェクトを作成する
概要
記事一覧はこちらです。
ユーティリティーファーストとTailwind CSSのススメ の記事を読んで React+Tailwind CSS の組み合わせに興味を持ったのでサンプルプロジェクトを作成してみます。作成した Component を確認できるよう Storybook も入れてみます。
Typescript は導入せず Javascript で記述する想定です。
Node.js、npm、yarn は以下のバージョンを使用しています(Node.js と npm のバージョンが古いな。。。とは思いつつ今回はこのままでいきます)。
参照したサイト・書籍
ユーティリティーファーストとTailwind CSSのススメ
https://qiita.com/Takazudo/items/5180f5eb6d798a52074fTailwind CSS
https://tailwindcss.com/tailwindlabs / tailwindcss-forms
https://github.com/tailwindlabs/tailwindcss-formspostcss / postcss - PostCSS 8 for end users
https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users- ツールの PostCSS 8 の対応状況が表示されています。
Install Tailwind CSS with Create React App
https://tailwindcss.com/docs/guides/create-react-appgsoft-inc / craco
https://github.com/gsoft-inc/cracoInstallation
https://tailwindcss.com/docs/installationConfiguration
https://tailwindcss.com/docs/configurationtailwindcss init
コマンドの-p
flag の説明はここに記述されていました。
Storybook
https://storybook.js.org/Install Storybook
https://storybook.js.org/docs/react/get-started/installIntroduction to Storybook for React
https://storybook.js.org/docs/react/get-started/introductionIntegrating React, Tailwind and Storybook
https://johnclarke73.medium.com/integrating-react-tailwind-and-storybook-3ae124aff0d9Storybook-tailwind. How should I add tailwind to storybook
https://stackoverflow.com/questions/65495912/storybook-tailwind-how-should-i-add-tailwind-to-storybook
目次
- create-react-app で react-taiwindcss-storybook-sample プロジェクトを作成する
- Tailwind CSS をインストールする
- CRACO をインストール・設定する
npx tailwindcss init -p
コマンドを実行して tailwind.config.js、postcss.config.js を作成する- src/index.css を変更する
- src/App.css、src/App.js を変更して Tailwind CSS が利用できることを確認する
npx sb init
コマンドを実行して Storybook をインストールする- babel-loader が 8.2.2 にバージョンアップされて
yarn start
実行時にエラーが出るので 8.1.0 にバージョンダウンする - .storybook/preview.js、.storybook/main.js を変更する
- src/stories を削除する
- component のサンプルを作成して Storybook 上に表示する
手順
create-react-app で react-taiwindcss-storybook-sample プロジェクトを作成する
コマンドプロンプトから以下のコマンドを実行し、プロジェクトを作成します。
cd /d/project-react/
npx create-react-app react-taiwindcss-storybook-sample
cd react-taiwindcss-storybook-sample/
yarn test
を実行してテストが正常に終了することを確認します。yarn start
を実行してブラウザに React のロゴが表示されることを確認します。
Tailwind CSS をインストールする
Install Tailwind CSS with Create React App のページを参考に以下のコマンドを実行します。@tailwindcss/forms もインストールします。Tailwind CSS は PostCSS 8 に対応しているのですが create-react-app がまだ対応していないらしく、PostCSS 7 を使うようにする必要があるとのこと。
yarn add tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
※(2021/04/20追記)postcss、autoprefixer はyarn add -D
でインストールした方がよい。yarn add @tailwindcss/forms
CRACO をインストール・設定する
引き続き Install Tailwind CSS with Create React App のページを参考に yarn add @craco/craco
コマンドを実行して CRACO をインストールします。create-react-app の PostCSS の設定を変更するためにこのツールが必要とのこと。
package.json 内の scripts で react-scripts
→ craco
に変更します。
"scripts": { "start": "craco start", "build": "craco build", "test": "craco test", "eject": "craco eject" },
プロジェクトのルートディレクトリ直下に craco.config.js を作成し、以下の内容を記述します。
module.exports = { style: { postcss: { plugins: [ require('tailwindcss'), require('autoprefixer'), ], }, }, }
npx tailwindcss init -p
コマンドを実行して tailwind.config.js、postcss.config.js を作成する
Installation のページを参考に npx tailwindcss init -p
コマンドを実行して tailwind.config.js、postcss.config.js を作成します。
tailwind.config.js は以下の内容に変更します。
module.exports = { purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'], darkMode: false, // or 'media' or 'class' theme: { extend: {}, }, variants: { extend: {}, }, plugins: [ require('@tailwindcss/forms'), ], }
- purgeに
'./src/**/*.{js,jsx,ts,tsx}', './public/index.html'
を追加します。 - plugins に
require('@tailwindcss/forms'),
を追加します。
postcss.config.js は作成されたままで何も変更しません。
module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, }, }
src/index.css を変更する
src/index.css の中身を全てクリアし、以下の内容に変更します。
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind forms;
src/App.css、src/App.js を変更して Tailwind CSS が利用できることを確認する
Tailwind CSS が利用できるようになっていることを確認します。
src/App.css の中身はどれも使用しないので全てクリアします。
src/App.js を Tailwind CSS を利用して文字列を表示するよう以下の内容に変更します。
import './App.css'; function App() { return ( <div className="pt-4 pl-4 text-red-600 text-4xl font-extrabold"> React+Tailwind CSS </div> ); } export default App;
yarn start
を実行すると、
ブラウザに以下のように表示されました。問題なく利用できるようになっています。
npx sb init
コマンドを実行して Storybook をインストールする
Install Storybook のページを参考に npx sb init
コマンドを実行して Storybook をインストールします。
..........
yarn storybook
コマンドを実行して、
..........
Storybook の画面が表示されることを確認します。
babel-loader が 8.2.2 にバージョンアップされて yarn start
実行時にエラーが出るので 8.1.0 にバージョンダウンする
Storybook をインストールした後に yarn start
を実行すると "babel-loader": "8.1.0"
が必要とのエラーが出ます。
yarn.lock を見ると babel-loader が 8.2.2 になっていました。yarn add -D babel-loader@8.1.0
を実行してバージョンダウンします。
バージョンダウン後、再度 yarn start
を実行すると今度は画面が表示されました。
.storybook/preview.js、.storybook/main.js を変更する
Tailwind CSS が適用されるよう .storybook/preview.js、.storybook/main.js を変更します。
.storybook/preview.js を以下のように変更します。
import '../src/index.css'; export const parameters = { actions: { argTypesRegex: "^on[A-Z].*" }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }
import '../src/index.css';
を追加します。
.storybook/main.js を以下のように変更します。Integrating React, Tailwind and Storybook や Storybook-tailwind. How should I add tailwind to storybook を見てコピペしました。
const path = require('path'); module.exports = { "stories": [ "../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)" ], "addons": [ "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/preset-create-react-app" ], webpackFinal: async (config) => { config.module.rules.push({ test: /\,css&/, use: [ { loader: 'postcss-loader', options: { ident: 'postcss', plugins: [ require('tailwindcss'), require('autoprefixer') ] } } ], include: path.resolve(__dirname, '../'), }) return config } }
const path = require('path');
を追加します。webpackFinal: async (config) => { ... }
を追加します。
src/stories を削除する
src/stories に Storybook のサンプルが作成されていますが、不要なので削除します。
component のサンプルを作成して Storybook 上に表示する
src/components/sample ディレクトリを作成し、その下に ListItem.js、List.js の2つの component を作成します。
まずは ListItem.js から。以下の内容を記述します。
import React from 'react'; const ListItem = ({image, title, author}) => ( <article className="p-2 flex space-x-4"> <img className="flex-none w-16 h-16 rounded-lg" src={image} alt=""/> <div> <dl> <div> <dt className="sr-only">Title</dt> <dd className="text-2xl font-bold">{title}</dd> </div> <div className="mt-0.5"> <dt className="sr-only">Author</dt> <dd className="text-sm font-semibold text-indigo-500">By {author}</dd> </div> </dl> </div> </article> ); export default ListItem;
同じ階層に ListItem.stories.js を作成し、以下の内容を記述します。
import React from 'react'; import ListItem from './ListItem'; import dog from './dog.jpg'; export default { title: 'sample/ListItem', component: ListItem, }; const Template = (args) => <ListItem {...args}/>; export const Default = Template.bind({}); Default.args = { image: dog, title: 'サンプルブック1', author: '作者は犬', };
Storybook で ListItem component を表示すると以下のように表示されました。
次は List.js。以下の内容を記述します。
import React from 'react'; import ListItem from "./ListItem"; const List = ({items}) => ( <ul className="divide-y divide-gray-600"> {items.map(item => ( <ListItem key={item.title} {...item}/> ))} </ul> ); export default List;
同じ階層に List.stories.js を作成し、以下の内容を記述します。
import React from 'react'; import List from './List'; import dog from './dog.jpg'; import cat from './cat.jpg'; import tiger from './tiger.jpg'; export default { title: 'sample/List', component: List, }; const Template = (args) => <List {...args}/>; export const Default = Template.bind({}); Default.args = { items: [ { image: dog, title: 'サンプルブック1', author: '作者は犬', }, { image: cat, title: 'サンプルブック2', author: '作者は猫', }, { image: tiger, title: 'サンプルブック3', author: '作者はトラ', }, ] };
Storybook で List component を表示すると以下のように表示されました。
履歴
2021/04/17
初版発行。
2021/04/20
* yarn add babel-loader@8.1.0
→ yarn add -D babel-loader@8.1.0
に変更しました。
* <ListItem {...item}/>
→ <ListItem key={item.title} {...item}/>
に変更しました。