Closed23

Next13 × Storybook7を試す

hajimismhajimism

Next12からの移行というテイで試したいので、最初にnpx sb init --builder webpack5したあとでnpx storybook@next upgrade --prereleaseする

hajimismhajimism

.storybook/main.js

特筆
stories: これに基づいてstoryのtitleを自動で付与してくれるらしい。'../components/'以下のComponent.stories.tsxファイルならタイトルがcomponents/Componentになるなど。
addons: Tailwindを使いたかったのでpostcssのaddonを追加した。

module.exports = {
  stories: [
    { directory: '../app/', files: '*.stories.tsx', titlePrefix: 'pages' },
    '../components/',
  ],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
    {
      name: '@storybook/addon-postcss',
      options: {
        postcssLoaderOptions: {
          implementation: require('postcss'),
        },
      },
    },
  ],
  framework: {
    name: '@storybook/react-webpack5',
    options: {},
  },
  docs: {
    autodocs: true,
  },
}

.storybook/preview.js

特筆
nextjs: ページコンポーネントが全部appDirにあるならtrueにしろとのこと

import '../styles/globals.css'

export const parameters = {
  nextjs: {
    appDirectory: true,
  },
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
}
hajimismhajimism

あれ、main.jsのframework.nameが自動でなおってないな。

Manual upgrade guideの方にこう書いてあるので修正

// .storybook/main.js
module.exports = {
  // ...
  framework: {
    // name: '@storybook/react-webpack5', // Remove this
    name: '@storybook/nextjs', // Add this
    options: {},
  },
};
hajimismhajimism

自動で作られるstoryディレクトリを削除して、app以下にTopページのStoryを作る。
レイアウトあり・なしで一応2つ記述したけどもっとうまい書き方がある?

import React from 'react'
import { StoryObj, Meta } from '@storybook/react'
import HomePage from './page'
import RootLayout from './layout'

const meta: Meta<typeof HomePage> = {
  component: HomePage,
  parameters: {
    layout: 'fullscreen',
  },
}

export default meta

type Story = StoryObj<typeof HomePage>

export const WithoutLayout: Story = {
  render: () => <HomePage />,
}

export const WithLayout: Story = {
  render: () => (
    <RootLayout>
      <HomePage />
    </RootLayout>
  ),
}
hajimismhajimism

ここで立ち上げてみるとエラーが出る

ModuleBuildError: Module build failed (from ../../node_modules/babel-loader/lib/index.js):
SyntaxError: [作業ディレクトリ]/app/Home.stories.tsx: Missing initializer in const declaration. (5:10)

  3 | import HomePage from './page';
  4 | import RootLayout from './layout';
> 5 | const meta: Meta<typeof HomePage> = {
    |           ^
  6 |   component: HomePage,
  7 |   parameters: {
  8 |     layout: 'fullscreen'
hajimismhajimism

さっきの自動upgradeがうまく言ってなかったところを睨んで、下記をしたらなおった

yarn add --dev @storybook/nextjs@next
hajimismhajimism

てことで無事表示🎉
タイトル自動付与はマジだった

hajimismhajimism

/components/以下にもStory作ってみたけど、title prefixついてなかったのでmain.jsを修正した。

  stories: [
    { directory: '../app/', files: '*.stories.tsx', titlePrefix: 'pages' },
    {
      directory: '../components/',
      files: '*.stories.tsx',
      titlePrefix: 'components',
    },
  ],
hajimismhajimism

ちなみに yarn storybookだと長いのでpackage.jsonをいじってyarn sbで動くようにしている

hajimismhajimism

今はこれ以上特にできることないので、ドキュメントを流し読んで注意点をさらっておく
https://github.com/storybookjs/storybook/tree/next/code/frameworks/nextjs

hajimismhajimism

AVIF
This format is not supported by this framework yet. Feel free to open up an issue if this is something you want to see.

hajimismhajimism

If your Next.js project uses the app directory for every page (in other words, it does not have a pages directory), you can set the parameter nextjs.appDirectory to true in the preview.js file to apply it to all stories.

// .storybook/preview.js

export const parameters = {
  nextjs: {
    appDirectory: true,
  },
};
hajimismhajimism

preview.jsでも絶対パスでのimportができるらしいので試してみたけどbroken builedとなった

// .storybook/preview.js

import 'styles/globals.scss';

// ...
hajimismhajimism

Storybook楽しいので、ふつうに機能探訪したい。また別スクラップで。

このスクラップは2023/01/10にクローズされました