Open7

storybook-vite

piyokopiyoko

参考

https://storybook.js.org/blog/storybook-for-vite/

StoryBook

UIのカタログを作るツールで、個別のコンポーネント単体の動作・UIの確認ができます。
https://storybook.js.org/
https://github.com/storybookjs/builder-vite

インストール

npx storybook init --builder @storybook/builder-vite

storybook をインストールしていいか聞かれるので yes

Need to install the following packages:
  storybook
Ok to proceed? (y)

eslint-plugin-storybook をインストール していいか聞かれるので yes

eslint-plugin-storybook をインストール は 成功したけど、アプリ内の eslint設定ファイルが yaml なので設定できなかった。
サポートしているのは js と cjs だけなので json でも設定できない。

どちらか言うと、インストールは自分でできるから設定はしてほしいんだけど・・・

piyokopiyoko

2020/05/20 こんだけdevDependencies で インストールされた。
babel 入るんがやだなぁ

@babel/core: v7.18.0,
@storybook/addon-actions: v6.5.3,
@storybook/addon-essentials: v6.5.3,
@storybook/addon-interactions: v6.5.3,
@storybook/addon-links: v6.5.3,
@storybook/builder-vite: v0.1.35,
@storybook/react: v6.5.3,
@storybook/testing-library: v0.0.11,
babel-loader: v8.2.5,
eslint-plugin-storybook: v0.5.12,

package.json の scripts にも追加してくれてる

"scripts": {
・・・
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"

src直下にstoriesフォルダができてる

root直下に .storybook フォルダができてる

piyokopiyoko

とりあえず実行してみる

npm run storybook

Windows Defender ファイアウィールでブロックされたと警告がでる。

アクセスを許可しなくても storybook が立ち上がった。なので許可する必要はないかな。

piyokopiyoko

まずはここ読む

https://github.com/storybookjs/builder-vite

Vite構成をカスタマイズする

ビルダーはデフォルトでは vite.config.ts ファイルを読み取らないので、設定を読み込むようにする。
ただし、公式サイトの方法では読み込めなかった。

src 直下を@で読み込めるように vite.config.ts の alias を設定しているのですが、ストーリーファイルの中で使えなかった。

  1. エラーがわかりにくいので、main.js を main.ts に変更する。
    拡張子を変えるだけで Typescript として認識してくれる。

2.main.ts を以下のように変更する。
参考:https://github.com/storybookjs/builder-vite/issues/85

.storybook/main.ts
+ const path = require("path");
+ const { loadConfigFromFile, mergeConfig } = require('vite');

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions"
  ],
  "framework": "@storybook/react",
  "core": {
    "builder": "@storybook/builder-vite"
  },
  "features": {
    "storyStoreV7": true
  },
+  async viteFinal(config, { configType }) {
+     const { config: userConfig } = await loadConfigFromFile(
+       path.resolve(__dirname, "../vite.config.ts")
+     );
+ 
+    return mergeConfig(config, {
+      ...userConfig,
+      // manually specify plugins to avoid conflict
+      plugins: [],
+    });
+  },
};

ここ見て自分で .eslintrc に設定する。
https://github.com/storybookjs/eslint-plugin-storybook#usage
eslint-plugin-storybook の オススメ設定を *.stories.@(ts|tsx|js) のファイルにのみ適用させる

.eslintrc.yml
・・・
extends:
  - plugin:react/recommended
  - plugin:react-hooks/recommended
  - airbnb
  - airbnb-typescript
  - prettier
overrides:
  - files:
      - '**/__tests__/**/*.+(ts|tsx|js)'
      - '**/?(*.)+(spec|test).+(ts|tsx|js)'
    extends:
      - plugin:jest-dom/recommended
      - plugin:testing-library/react
+  - files:
+      - '*.stories.@(ts|tsx|js)'
+    extends:
+      - plugin:storybook/recommended
+    rules:
+      # default export を許可する
+      import/no-default-export: off
ignorePatterns:
  - vite.config.ts
  - vitest.setup.ts
settings:
  import/resolver:
    typescript: []
rules:
  ・・・
piyokopiyoko

エラーを解消

lint を実行して、eslint の設定次第でエラーがでるので修正する。

piyokopiyoko

vite.config.ts が読み込めているか確認のためにもサンプル作る

コンポーネント作成
src/mycomponent/MyButton.tsx
src/mycomponent/index.ts

サンプル

mycomponent/MyButton.tsx
import { Button } from '@mui/material'

export type MyButtonProps = {
  text: string
}

export const MyButton = ({ text }: MyButtonProps) => {
  return (
    <Button variant="contained" size="small" color="warning">
      {text}
    </Button>
  )
}
mycomponent/index.ts
export * from './MyButton'

ストーリーファイル作成
src/stories/MyButton.stories.tsx

import { ComponentStory, ComponentMeta } from '@storybook/react'

// vite.config.ts が読み込みできていれば、エイリアスパスでimportできる。
import { MyButton } from '@/mycomponent'

export default {
  title: 'MyComponent/MyButton',
  component: MyButton,
  // TODO:これ解らんわ。無くてもエラーにならんし。後で調べる
  // argTypes: {
  //   backgroundColor: { control: 'color' }
  // }
} as ComponentMeta<typeof MyButton>

const Template: ComponentStory<typeof MyButton> = (args) => <MyButton {...args} />

export const Primary = Template.bind({})

Primary.args = {
  text: 'Button'
}

できた。