みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Next.js + styled-componentsのプロジェクトにStorybookを導入する 📕


Storybookとは

StorybookはUIコンポーネントの開発環境です。
コンポーネントライブラリを参照したり、各コンポーネントの状態を表示したり、コンポーネントをテストしたりできるものです。

storybook.js.org

Storybook導入手順

今回はNext.jsに組み込んで使ってみようと思います。
手順は、かつては公式のブログにまとまっていたのですが、先ほど確認したらドキュメント内に記述を見つけました。

Next.jsとの組み合わせ

storybook.js.org

styled-componentsとの組み合わせ

storybook.js.org

ドキュメント

storybook.js.org

さっそく導入を試してみたところ、ドキュメントの通り、

npx storybook@latest init

で一発で設定できました。
ログに、

• Adding Storybook support to your "Next" app
✔ Getting the correct version of 10 packages
Configuring Storybook ESLint plugin at .eslintrc.json
✔ Installing Storybook dependencies
. ✓

と表示されたので、Next.jsに導入しようとしていることを検知して自動でもろもろセットアップしてくれるようです。
具体的になにをしているのかを探ってみると、

package.jsonを編集。

{
  "scripts": {
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "dependencies": {
    "next": "14.2.3",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@chromatic-com/storybook": "^1.5.0",
    "@storybook/addon-essentials": "^8.1.5",
    "@storybook/addon-interactions": "^8.1.5",
    "@storybook/addon-links": "^8.1.5",
    "@storybook/addon-onboarding": "^8.1.5",
    "@storybook/blocks": "^8.1.5",
    "@storybook/nextjs": "^8.1.5",
    "@storybook/react": "^8.1.5",
    "@storybook/test": "^8.1.5",
    "eslint-plugin-storybook": "^0.8.0",
    "storybook": "^8.1.5",
  }
}

設定に必要なファイルの作成。

.storybook/main.ts
.storybook/preview.ts

.gitignoreファイルに追記

*storybook.log

をしつつ、src/stories以下にUIの例を作成し、http://localhost:6006/を起動してくれます。

ものすごく簡単にセットアップできて驚きました。
昔は、もっと手順があった気がするんですが。時代の流れを感じますね。(気のせいかもしれません)

Storybook設定方法

そのまま使ってもOKなのですが、僕は.storybook/preview.tsを.storybook/preview.tsxに編集しています。

.storybook/preview.tsx

import '@/styles/global.scss'; // グローバルスタイルの追加
import styled from 'styled-components';
import React from 'react'; // Reactの読み込み
import type { Preview } from '@storybook/react';

const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
  decorators: [
    (Story) => {
      return (
        <Wrapper>
          <Story />
        </Wrapper>
      );
    },
  ],
};

export default preview;

const Wrapper = styled.div`
  background: red; // 背景色を(使ってない色に)設定
  transform: translate3d(0, 0, 0); // fixedのコンポーネントを無効化したいので設定
`;

という感じで、decoratorsを設定しています。
translate3dは状況をみて設定していますが、グローバルスタイルの読み込みと背景色は設定しておくと便利です。