10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

1人フロントエンドAdvent Calendar 2022

Day 9

【バージョン7.0先取り】Beta版になったStorybook 7.0のVite×React環境における変更

Last updated at Posted at 2022-12-08

はじめに

Storybookを用いてフロントエンドの開発を行うことはとても体験がよく重宝しています。そんなStorybookの最新バージョンである7.0のベータ版が昨夜(2022/12/8)リリースされました。
この記事ではVite×Reactに関係するStorybook 7.0の機能について解説を行います。
Storybookの7.0への移行ガイドはこちらになります。
この記事はBeta版での解説ですのでリリース時には異なる内容になっている可能性があります。

Viteを使ったStorybookの環境構築

storybookでvite環境を作るには一つのコマンドだけが必要です。以下のコマンドを入力すると最新バージョンの環境が手に入ります。

npx sb@latest init --builder=vite

これによって.storybookフォルダが作成され、main.cjspreview.cjspreview-head.htmlが生成されます。またサンプルとしてsrc配下にstoriesディレクトリが生成され、ボタンなどのコンポーネントとstoryが準備されます。どの様なファイルが含まれていて、内容がどうなっているかはこの記事には大きく関係しないので自分で構築して確かめて下さい。

7.0と比較

先ほどのコマンドによって生成されたファイルを7.0のものと比較します。執筆当時の最新バージョンである6.5.14と最新のベータバージョンである7.0.0-beta.0比較を行います。最新のベータバージョンはnextを指定することで得られます。

npx sb@next init --builder=vite

変更は3点です。main.cjsと各storiesファイル、storybookのscriptsコマンドです。

main.cjs

6.5.14では以下のようになっています。

latest
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
  }
}

7.0.0-beta.0では以下のようになっています。pathは使っていないので以後考えないことにします(消しても良いと思います)。

next
const path = require('path');
module.exports = {
  "stories": [
    "../src/**/*.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions"
  ],
  "framework": {
    "name": "@storybook/react-vite",
    "options": {}
  },
  "docs": {
    "docsPage": true
  }
}

変更はこの部分です。

-  "framework": "@storybook/react",
-  "core": {
-    "builder": "@storybook/builder-vite"
-  },
-  "features": {
-    "storyStoreV7": true
-  }
+  "framework": {
+    "name": "@storybook/react-vite",
+    "options": {}
+  },
+  "docs": {
+    "docsPage": true
+  }

フレームワークが@storybook/reactから@storybook/react-viteになり、coreの設定が消えました。これはframworkにUIライブラリとbuilderを組み合わせた値を渡せるようになり、まとめて記述することになったからです。
次にfeaturesが消えました。7.0の機能を先取りする機能みたいなものなので、7.0になったら消えるのが当然のものです。
最後にdocsが追加されています。7.0ではDocs周りの機能が大きく変わっています。これまではStoryを記述すれば自動的にDocsも記述されて、CanvasとDocsを切り替えることでDocsの確認をすることができました。
スクリーンショット 2022-12-08 18.41.17.png
7.0ではDocsの自動生成がデフォルトではされなくなりました。従来通り記述させたい場合はdocsPage"automatic"に設定することで自動的に生成されるようになります。さらに、画面上部で行うDocsとCanvasの切り替えではなくなりコンポーネントの切り替えと同じように切り替えるようになりました。
スクリーンショット 2022-12-08 18.44.38.png
docsPagefalseにすると完全にDocsが生成されなくなるので注意して下さい。デフォルトになったtrueの時のDocsの生成方法はstoriesファイルの説明の時に行います。

stories

storyの書き方は大きく変わりました。CSF2の記法だったものからCSF3に移行しました。まずは見比べてみましょう。まずは6.5.14の書き方です。

Button.stories.tsx
import { ComponentStory, ComponentMeta } from '@storybook/react';

import { Button } from './Button';

export default {
  title: 'Example/Button',
  component: Button,
} as ComponentMeta<typeof Button>;

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

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

次に7.0.0-beta.0の書き方です。

Button.stories.ts
import type { Meta, StoryObj } from '@storybook/react';

import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Example/Button',
  component: Button,
};
export default meta;

export const Primary: StoryObj<typeof Button> = {
  args: {
    primary: true,
    label: 'Button',
  },
};

あまりにも変更が大きいですね。7.0.0-beta.0の方が記述が簡素になっていることがわかると思います。
まず、7.0ではComponentMetaやStory、ComponentStory、ComponentStoryFn、ComponentStoryObjが非推奨になってしまいました。それぞれMeta、StoryFn、StoryObjに置き換える必要があります(ComponentMeta=>Meta、Story=>StoryFn、ComponentStory=>StoryObj、ComponentStoryFn=StoryFn、ComponentStoryObj=StoryObj)。
次にmetaのdefault exportの方法が変わりました。これは元の記法でも動きますので変更する必要はないです。私はasを使わない新記法が好みです。型はComponentMetaからMetaに変える必要があります。
最後にStoryの記法が大きく変わりました。TemplateのようにComponentStoryを別で定義する必要はなくなり、必要なオブジェクトを定義したStoryObjをnamed exportするだけでStoryの定義が可能になりました。例ではargsだけをキーに持ってますが、playdecoratorsなどこれまで別々に宣言していたものが一つにまとめて宣言できるようになりました。
これらはCSF2からCSF3に移行するための変更ですので下のコマンドを用いてアップグレードできます。ぜひご利用ください。

npx sb@next migrate csf-2-to-3 --glob="**/*.stories.js"

main.cjsの設定でdocsPagetrueにした場合はStoryの設定ファイルでDocsの定義ができます。metaを以下のようにすることでそのStoryのDocsを生成させることができます。各Storyで定義するのが億劫でこれまで通りを望んでいる場合はdocPage"automatic"に変更して下さい。

const meta: Meta<typeof Button> = {
  title: 'Example/Button',
  component: Button,
  tags: ['docsPage'],
};

コマンド

storybookではこれまでstart-storybookbuild-storybookコマンドを用いて起動、ビルドを行っていました。package.jsonにはこの様に書かれていました。

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

7.0ではこれらのコマンドが一つに統一されます。

{
  "scripts": {
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  }
}

さらにNode17以降でStorybookを利用する際に必要だったNODE_OPTIONSである--openssl-legacy-providerを設定する必要がなくなりました。NODE_OPTIONS=--openssl-legacy-provider npm run storybookとする手間がなくなったので大変助かります。

その他

他に関係ありそうな変更を紹介します。

ルートタグのidの変更

storybookのコンポーネント表示を開始するタグのidをrootからstorybook-rootに変更されました。buttonのコンポーネントは下の様に変化しました。

従来
<div id="root">
  <button>Submmit</button>
</div>
7.0
<div id="storybook-root">
  <button>Submmit</button>
</div>

これによってidの競合による動作不良の頻度が減少しました(storybook-rootをidに指定することはほとんどアプリではないので)。

IE11非対応

Viteも基本非対応ですが@vitejs/plugin-legacyを使うなどして対応している場合もあるので書きました。storybookはこれまでIE11にも対応していましたが、IE11も含めレガシーバージョンブラウザへの対応をやめました。React18でもIE11の対応をやめているので今後も対応し続けるのがかなり難しくなってきた印象です。

Color Mode

どこにも書いてませんでが、7.0からOSのLight/Dark Modeを読み取って自動でModeを設定してくれるようになりました。
同じ環境でも7.0よりも前と後のもので比べると以下のようになります。
スクリーンショット 2022-12-08 21.26.48.png
スクリーンショット 2022-12-08 21.26.33.png
実装しているアプリケーションによってはColor Modeを実装しておらず白背景に表示することを前提としているためにコンストラストの関係でコンポーネントが見えにくくなることあります。そうした場合はpreview.cjsparametersオブジェクトに下のように追加して下さい。表示されるコンポーネントの背景が白になるのでアプリケーションの表示通りに開発を行うことができます。

preview.cjs
export const parameters = {
  backgrounds: {
    default: 'light'
  },
};

ベータ版へのアップデート

これまでは新しく環境を作成してバージョンによる差分を紹介して比較してきました。しかし、多くのユーザーはすでに利用しているstorybookからのアップデートを行うことがほとんどです。アップデートを行う場合は以下のコマンドを入力します。

npx sb@next upgrade --prerelease

入力するとコマンドラインでファイルの更新についていくつか聞かれます。実行コマンドの書き換え、main.cjsframeworkの書き換え、mdxを使っている場合はmd1からmd2への書き換え、Docsの自動生成のための設定(docsPage: 'automatic')を行なってくれます。
このコマンドによる変化はpackage.jsonでstorybook類のバージョンアップとscriptsの書き換え、main.cjsの書き換えを行なってくれます。書き換え後のmain.cjsは以下の通りです。

main.cjs
module.exports = {
  "stories": ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  "addons": ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions"],
  "framework": {
    name: "@storybook/react-vite",
    options: {}
  },
  "core": {},
  "features": {
    "storyStoreV7": true
  },
  docs: {
    docsPage: "automatic"
  }
};

coreやfeaturesは意味をなしていないので消しても構いません。自動で色々設定してくれるのでとても助かります。
削除後はmigrate csf-2-to-3などでstoriesファイルをCSF2からCSF3に移行すれば完了です。

10
2
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
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?