Pug使用の ただのnpm scriptタスクランナ環境でstorybookを使う
やること
フレームワークを使用していない、ただのnpm scriptタスクランナー(CSS:Sass、HTML:Pug、Javascript:Typescript、...その他好きに用意しているタスク群)でstorybookを使うのをやってみる
コンポネはPugで書いて、コピーするコードもPugがいい
SPAではないので、もともとの開発環境にはドッキングさせず使いたい(依存を深くもたせず、すぐアップデートできる、または切り離せる状態にしておきたい)
最初のコマンド
npx -p @storybook/cli sb init -t html
追加されるディレクトリと更新ファイル
追加されたディレクトリ
.storybook/ ← storybook設定JS
stories/ ← storybookのコンポネ群
package.json のscript更新
"storybook": "start-storybook -s _サイトルートパス_ -p 6006 --no-manager-cache",
"build-storybook": "build-storybook -o _ビルド時のコンパイル先パス_"
サイトルートパスやビルド時のコンパイル先パスは追加で設定
Pugの設定
コードをPugで書く
storypug をいれる
main.js (storypug公式どおり)
module.exports = {
addons: [
{
name: 'storypug',
options: {babel: true, loaderOptions: {root: 'src/_devassets/_pug'}},
},
],
};
./stories/component/Text.stories.ts
import startCase from 'lodash/startCase';
import { Meta, Story } from '@storybook/html';
import { renderer } from 'storypug';
const { render } = renderer({ startCase });
const Text = require('./Text.pug'); // pugファイルにして外出し
export default {
title: 'Component/Text',
argTypes: {
size: {
control: { type: 'radio', options: ['none', 'sm'] },
},
color: {
control: { type: 'radio', options: ['none', 'black', 'blue', 'red', 'supple', 'auxil'] },
defaultValue: 'none',
},
},
} as Meta;
const Template: Story = (args) => {
const wrapper = render(Text, args);
const div = document.createElement('div');
div.append(wrapper.$root);
return div.innerHTML; // 公式のまま(wrapper.$root;)だとDocsでエラーが出て変更
};
export const body = Template.bind({});
body.args = {
size: 'none',
};
export const sm = Template.bind({});
sm.args = {
size: 'sm',
};
./stories/component/Text.pug
mixin dom (args = {})
- const props = Object.assign({}, args)
- const classes = `${props.color !== 'none' ? ` c-color-${props.color}` : '' }`
p.c-txt(class=`${classes}`) テキストテキストテキストテキスト
コピーするコードをPug変換する
この記事を参考に html2jade を噛ませて変換をかける
./storybook/preview.js
import renderToHtml from './renderToHtml';
export const parameters = {
docs: {
transformSource: (src, storyContext) => renderToHtml(storyContext.storyFn),
},
};
.storybook/renderToHtml.js
import { renderToStaticMarkup } from 'react-dom/server';
import { AllHtmlEntities } from 'html-entities';
const entities = new AllHtmlEntities();
export default (story) => {
let html = entities.decode(renderToStaticMarkup(story()));
const html2pug = require('html2jade');
html2pug.convertHtml(html, { donotencode: true }, (err, pug) => {
if (err) {
throw new Error(err);
} else {
html = pug;
}
});
return html;
};
そのほか遭遇したエラー
pug変換したらfsエラーがでる: Module not found: Error: Can't resolve 'fs' in
こちらで解消
@whitespace/storybook-addon-html を入れるとHTMLタブでエラーがでる: Cannot convert undefined or null to object
こちらで解消
サイトのスタティックなcommon.jsをプレビュー画面で実行させたい
DOMContentLoadedが効かないらしい...
こちらのdecoratorで対応
MutationObserverを使うやり方もあるらしい
storybookのルーターイベント取得方法を調べ中
入れたアドオン一覧
@babel/core => 勝手にる
@storybook/html => 勝手に入る
@storybook/addon-essentials => storybookの標準便利機能を使うため入れる
@storybook/addon-links => 同上
storypug => コンポネをpugで書くために入れる
html2jade => 「copy code」でpug変換させるために入れる
@whitespace/storybook-addon-html => HTMLタブも欲しくて入れる
@storybook/react => プレビューエリアをカスタマイズしたくて入れる
html-to-react => プレビューエリアにdecoratorで変換を加えたくて入れる
@storybook/theming => storybook自体のテーマを変えたくて入れる
Discussion