Svelte3のプロジェクトにStorybookを導入する
Install Storybookに従って、既存の Svelte3 プロジェクトに導入してみる。
使用している Storybook と Svelte のバージョンは次の通り。
- Storybook 6.1.18
- @storybook/svelte 6.1.18
- Svelte 3.32.3
Svelte3 プロジェクトは次の記事の通り Typescript、Pug, Sass を使えるようにしている。
インストール
$ npx sb init
実行すると次のディレクトリが作成される。
- .storybook
- src/stories
生成されるファイル群は次の通り。
ファイルツリーを開く
❯ tree .storybook src/stories
.storybook
├── main.js
├── preview.js
src/stories
├── Button.stories.js
├── Button.svelte
├── Header.stories.js
├── Header.svelte
├── Introduction.stories.mdx
├── Page.stories.js
├── Page.svelte
├── assets
│ ├── code-brackets.svg
│ ├── colors.svg
│ ├── comments.svg
│ ├── direction.svg
│ ├── flow.svg
│ ├── plugin.svg
│ ├── repo.svg
│ └── stackalt.svg
├── button.css
├── header.css
└── page.css
サンプルのストーリーが生成されている。
起動
インストールが終わったら次のコマンドで起動する。
$ yarn storybook
自動的にデフォルトブラウザが開き、サンプルの Storybook が参照できる。
ざっと触ってみる
src/stories ディレクトリ以下には、サンプルとなる Svelte コンポーネントとそれらに対応したストーリファイルが作成されていて、それらを参照できる。
コンポーネントの表示モードは Canvas と Docs の二種類ある。
Canvas
Canvas 表示では選択したストーリーでコンポーネントのみが表示される。
画面下部に表示される Control でコンポーネントの様々なパラメータを変更して試すこともできる。
また、背景をダークにしたり、グリッドの表示もできる。
更に、モバイル端末をエミュレートするためにプレビューのサイズ変更も可能となっている。
Docs
Docs 表示では選択したコンポーネントの ArgsTable とすべてのストーリーが表示される。
ArgsTable ではコンポーネントの引数をインタラクティブに変更できる。
Typescript 対応
Typescript や Pug、Sass を使ったコンポーネントを扱うためには svelte-preprocess
を使う。
Svelte は Rollup を利用するが、Storybook は Webpack を使うので、次の様に .storybook/webpack.config.js を追加する。
const sveltePreprocess = require("svelte-preprocess");
module.exports = async ({ config }) => {
const svelteLoader = config.module.rules.find(r => r.loader && r.loader.includes("svelte-loader"));
svelteLoader.options = {
...svelteLoader.options,
preprocess: sveltePreprocess(),
};
return config;
};
stories ディレクトリを変更する
npx sb init
コマンドを実行すると、ストーリーを置くディレクトリは src/stories に配置される。
src ディレクトリにはプロダクションコードのみを起きたいので stories ディレクトリを src 外に出したい。
まあ、好みの問題なので src/stories で気にならないならそのままで良い。
移動させたい場合には、ディレクトリを移動させた後、.storybook/main.js の stories
に設定する。
次の例は、<project-root>/src/stories から <project-root>/stories に移動したときの設定変更例。
module.exports = {
"stories": [
- "../src/**/*.stories.mdx",
- "../src/**/*.stories.@(js|jsx|ts|tsx)"
+ "../stories/**/*.stories.mdx",
+ "../stories/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials"
]
}
ViewPort アドオンの設定
Storybook は各種アドオンで機能追加することが可能になっている。
先に紹介したプレビューの表示サイズの変更も @storybook/addon-viewport
により実現されている。
@storybook/addon-viewport
は npx sb init
でインストールされる @storybook/addon-essentials
に含まれているので別途インストールは不要。
デフォルトでは表示サイズは Small mobile 、 Large mobile、Tablet といったざっくりした種類しか選べない。
次の設定を .storybook/preview.js に加えると iPhone X、iPad、Pixel といった代表的な端末サイズで選択できるようになる。
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; // <= 追加
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
viewport: { // <= 追加
viewports: INITIAL_VIEWPORTS, // <= 追加
}, // <= 追加
}
独自の表示サイズを追加したければ次のドキュメントに方法が記載されている。
独自のストーリーを追加する
次の様なコンポーネントのストーリーを作ってみる。これは Svelte の公式テンプレにある App.svelte を Typesctipt 、 Pug 、 Sass で書き直したもの。
<svelte:options tag="my-hello" immutable="{true}"/>
<script lang="ts">
export let name: string;
</script>
<template lang='pug'>
main
h1 Hello {name}!
p
| Visit the
a(href="https://svelte.dev/tutorial") Svelte tutorial
| to learn how to build Svelte apps.
</template>
<style lang='sass'>
main
text-align: center
padding: 1em
max-width: 240px
margin: 0 auto
h1
color: #ff3e00
text-transform: uppercase
font-size: 4em
font-weight: 100
@media (min-width: 640px)
main
max-width: none
</style>
Component Story Format (CSF)
標準のストーリーの記述書式。これで記述したストーリーは次の通り。
import App from '../src/App.svelte';
export default {
title: 'Components/App',
component: App,
parameters: {
docs: {
description: {
component: 'Svelte3 sanple app',
},
},
},
argTypes: {
name: {
type: { required: true },
description: 'text',
},
},
};
const Template = ({ ...args }) => ({
Component: App,
props: args,
});
export const World = Template.bind({});
World.args = {
name: 'world',
};
export const Hoge = Template.bind({});
Hoge.parameters = {
docs: {
description: {
story: 'Description of this story.',
},
},
};
Hoge.args = {
name: 'hoge',
};
これを表示した結果は次の通り。
Canvas
Dacs
MDX
MDX は Markdown の中に JSX を記述できるフォーマット[1]。ストーリーを記述するもう1つの形式である。
前述の CSF 形式での記述と同等の内容を記述した MDX は次の通り。
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks';
import App from '../src/App.svelte';
<Meta title="Components/App-MDX" component={App}
argTypes={{
name: {
type: { required: true },
description: 'text',
},
}}
/>
export const Template = ({ ...args }) => ({
Component: App,
props: args,
});
## App
Svelte3 sanple app
<Canvas>
<Story name='World'
args={{
name: 'world',
}}>
{Template.bind({})}
</Story>
</Canvas>
<ArgsTable story='World'/>
## Stories
### Hoge
Description of this story.
<Canvas>
<Story name='Hoge'
args={{
name: 'hoge',
}}>
{Template.bind({})}
</Story>
</Canvas>
Markdown で記述できるので長文のコンポーネントの説明を記述する場合には CSF よりも書きやすいと思う。
しかし、CSF では自動で入るストーリー毎のセクションタイトルなどを自分で記述する必要がある。
また、記述する上で細かに注意する必要な部分がある。例えば Canvas の閉じタグと ArgsTable タグの間に空行を入れないとレンダリングエラーが発生したりする[2]。
まとめ
Svelte3 のプロジェクトに Storybook を導入方法と Typescript に対応した設定、ViewPort アドオンの設定などを説明した。
また、ストーリファイルの作成についても紹介した。
Discussion