2023.1.31
Next.jsプロジェクトにStorybookとTailwindを導入してStorybookにTailwindのクラスによるスタイルを適用しStorybookのテストを通す
概要
Storybookを立ち上げてコンポーネントをブラウザで確認するとき、Tailwindのスタイルを適用する方法を公開します。
Storybook公式ドキュメントの Integrate Tailwind CSS and Storybook にTailwindとStorybookの連携方法がありますが、内容が古くてそのままでは動作しないところもあるため、記事にしておこうと思います。
最終的には @storybook/test-runner
まで導入し、StorybookのInteraction testsを通すところまで実装します。
Next.jsプロジェクトの作成
今回はせっかくなのでNext.jsのプロジェクトを作成するところからやりたいと思います。
bash_____terminal_____$ npx create-next-app --typescript
Ok to proceed? (y) y
✔ What is your project named? … next-tailwind-storybook
✔ Would you like to use ESLint with this project? … No / Yes
✔ Would you like to use `src/` directory with this project? … No / Yes
✔ Would you like to use experimental `app/` directory with this project? … No / Yes
✔ What import alias would you like configured? … @/*
Creating a new Next.js app in /Users/kobayashi/files/projects/io-kobayashiii/next-tailwind-storybook.
Using npm.
Installing dependencies:
- react
- react-dom
- next
- @next/font
- typescript
- @types/react
- @types/node
- @types/react-dom
- eslint
- eslint-config-next
added 270 packages, and audited 271 packages in 28s
102 packages are looking for funding
終わったら作成したプロジェクトのディレクトリに移動して yarn
or npm i
しておきます。
またこの記事ではyarnを利用するので package-lock.json
は削除しておきます。
Tailwindの導入
bash_____terminal_____yarn add -D tailwindcss postcss autoprefixer
bash_____terminal_____npx tailwindcss init -p
Created Tailwind CSS config file: tailwind.config.js
Created PostCSS config file: postcss.config.js
上記で生成された tailwind.config.js
を以下のように編集します。
JavaScript_____tailwind.config.js_____/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
};
続いて globals.css
を以下のように編集します。
css_____globals.css_____@tailwind base;
@tailwind components;
@tailwind utilities;
これで yarn dev
をして適当なタグに bg-gray-200
などクラスを付与して適用されれば導入完了です。
Storybookの導入
bash_____terminal_____npx storybook init
bash_____terminal_____yarn storybook
ブラウザで以下のような画面で npx storybook init
で作成されたサンプルのコンポーネントなどが確認できればOKです。
TailwindとStorybookの統合
bash_____terminal_____yarn add -D concurrently
続いて package.json
のscriptsに以下を追加します。
※scriptsに追加する部分だけ記載します。
json_____package.json_____{
// ...,
"scripts": {
// ...,
"build-storybook": "concurrently \"yarn:build:*\"",
"build:css": "npx tailwindcss -i ./src/styles/globals.css -o ./public/globals.css",
"build:storybook": "build-storybook",
"watch-storybook": "concurrently \"yarn:watch:*\"",
"watch:css": "npx tailwindcss -i ./src/styles/globals.css -o ./public/globals.css --watch",
"watch:storybook": "start-storybook -p 6006"
},
// ...
}
続いて以下のファイルを作成します。
html_____./storybook/preview-head.html_____<link href="/globals.css" rel="stylesheet" />
そして yarn watch-storybook
を実行し、最後に src/stories/Button.tsx
の {lable}
となっているところを試しに <span className="text-green-700">{label}</span>
としてみて、ブラウザで立ち上がっているStorybookの画面をリロードして文字が緑になっていればOKです。
リロードしなければいけないのは、現状でTailwindのクラスをあとからコンポーネントに付与してStorybookをホットリロードする方法がわからないためです。
2023/01/31時点で調べてみて見つかりませんでした。
Storybookのtest-runnerを導入
bash_____terminal_____yarn add -D @storybook/test-runner @storybook/addon-coverage
.storybook/main.js
のaddonsに @storybook/addon-coverage
を追加します。
JavaScript_____.storybook/main.js_____module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-coverage', // <- here
],
framework: '@storybook/react',
core: {
builder: '@storybook/builder-webpack5',
},
};
続いて package.json
のscriptsに以下を追加します。
json_____package.json_____{
// ...,
"scripts": {
// ...,
"test-storybook": "test-storybook --coverage"
},
// ...
}
最後に yarn test-storybook
でテストが通過したら完了です。
bash_____terminal_____yarn test-storybook
yarn run v1.22.19
$ test-storybook --coverage
PASS browser: chromium src/stories/Header.stories.tsx
PASS browser: chromium src/stories/Page.stories.tsx
PASS browser: chromium src/stories/Button.stories.tsx
Test Suites: 3 passed, 3 total
Tests: 8 passed, 8 total
Snapshots: 0 total
Time: 3.292 s
Ran all test suites.
Coverage file (8762 bytes) written to .nyc_output/coverage.json
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 81.81 | 100 | 66.66 | 81.81 |
Button.tsx | 100 | 100 | 100 | 100 |
Header.tsx | 100 | 100 | 100 | 100 |
Page.tsx | 66.66 | 100 | 50 | 66.66 | 18-19
------------|---------|----------|---------|---------|-------------------
✨ Done in 5.27s.