LoginSignup
9
1

More than 1 year has passed since last update.

StorybookのビルダーをwebpackからViteに変えた記録(Emotionも一緒)

Last updated at Posted at 2022-12-15

この記事の概要

Storybookを使っているプロジェクトがあるのですが、ビルダーをwebpackからViteに乗り換えたかったので調べてみました。
React + Emotionの環境です。

環境

モジュール バージョン
@emotion/react 11.9.0
@storybook/react 6.5.5
react 18.1.0
typescript 4.7.2
vite(今回追加) 4.0.0

やったこと

まずは以下のドキュメントの通りに進めました。

必要な依存関係をインストールします。
@storybook/builder-viteだけでは駄目で、自分でViteを入れる必要があります。

yarn add --dev vite @storybook/builder-vite

.storybook/main.jsを更新します。
Emotionを使っている関係でbabelの設定も入っています。

.storybook/main.js
  module.exports = {
    stories: ['../src'],
    addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
+   core: {
+     builder: '@storybook/builder-vite',
+   },
    framework: '@storybook/react',
    babel: async (options) => ({
      ...options,
      presets: [...options.presets, '@emotion/babel-preset-css-prop'],
    }),
  }

一度コマンドを叩いてみました。

yarn storybook

エラーが出ています。
.storybook/preview.jsの中でJSXの構文を使っているため、拡張子を.jsxにするように言われています。

Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension.
[vite] Internal server error: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension.

変更して再度Storybookを立ち上げました。

すると今度は立ち上がったものの、スタイルが当たっていません。
jsx pragmaを忘れたときと同じエラーが出ています。

エラー内容(改行して見やすくしたもの)
<div css="
  You have tried to stringify object returned from `css` function.
  It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop).
"></div>

色々調べているうちに以下のIssueにたどり着きました。

自分の環境だと@emotion/babel-pluginではなく、まだ@emotion/babel-preset-css-propを使っていたのでそれを変更しています。
あとexcludeにはデフォルトでnode_modulesが指定されているのもあり、若干怪しいです。
一応現段階だと、この指定を消しても動いているように見えています。

  const path = require('path')
+ const react = require('@vitejs/plugin-react')

  module.exports = {
    stories: ['../src'],
    addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
    core: {
      builder: '@storybook/builder-vite',
    },
    framework: '@storybook/react',
    babel: async (options) => ({
      ...options,
      presets: [...options.presets, '@emotion/babel-preset-css-prop'],
    }),
+   async viteFinal(config) {
+     config.plugins = config.plugins.filter(
+       (plugin) =>
+         !(Array.isArray(plugin) && plugin[0]?.name.includes('vite:react')),
+     )
+     config.plugins.push(
+       react({
+         exclude: [/\.stories\.(t|j)sx?$/, /node_modules/],
+         jsxImportSource: '@emotion/react',
+         babel: {
+           presets: ['@emotion/babel-preset-css-prop'],
+         },
+       }),
+     )
+     return config
+   },
  }

上記の設定で無事に動いたので、不要な設定を消します。

  const path = require('path')
  const react = require('@vitejs/plugin-react')

  module.exports = {
    stories: ['../src'],
    addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
    core: {
      builder: '@storybook/builder-vite',
    },
    framework: '@storybook/react',
-   babel: async (options) => ({
-     ...options,
-     presets: [...options.presets, '@emotion/babel-preset-css-prop'],
-   }),
    async viteFinal(config) {
      config.plugins = config.plugins.filter(
        (plugin) =>
          !(Array.isArray(plugin) && plugin[0]?.name.includes('vite:react')),
      )
      config.plugins.push(
        react({
          exclude: [/\.stories\.(t|j)sx?$/, /node_modules/],
          jsxImportSource: '@emotion/react',
          babel: {
            presets: ['@emotion/babel-preset-css-prop'],
          },
        }),
      )
      return config
    },
  }

最後に

Storybook自体というより、Emotionの設定に苦戦した感があります。
しかしこれでスピードも上がるしモダンな設定にもなるしで良かったです。

Storybookを使っているプロジェクトは多いと思うので、マイグレーションの参考になれば幸いです。


最後まで読んでくださってありがとうございます!
Twitterでも情報を発信しているので、良かったらフォローお願いします!

Devトークでのお話してくださる方も募集中です!

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1