16
12

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 3 years have passed since last update.

静的なWEBサイト用にも使えるstorybookのpug環境を作ってみた

Last updated at Posted at 2020-02-26

storybookって色々使い道があると思うのですが、動的なWEBサイト用の情報しか殆どないのでstorybook for htmlを静的WEBサイトでも使えるようなものを作ってみました。
やりたい事が形になったので紹介したいと思います。
gitも公開しているので良かったらお試しください。

story01.jpg

出来ること

・/stories以下のtree-title.stories.pugを/path/to/tree-titleへ自動追加(日本語も可)
・/stories以下のsassやstylusを自動で読み込み
・パネルにpugとhtmlのソース表示&コピー
・pugのmixinでコンポーネント作成し、knobsやテストをjsで記述可
・複数の環境に合わせて設定を変更して構築可

サブの環境として使えます

(.stories.)pug + sass,stylus + jqueryをデフォルトで使えるようにしてあるので、storybookやjsの知識があまり無い状態でも、マークアップからstorybook上での開発が進められるようにしてあります。
プロジェクトの本環境を作成している間に、コンポーネントを先に開発してもらうとか既存のgulp環境などの横に独立して並べて、stories以下のファイルを本環境でincludeして使用するみたいなことも可能です。

pugとhtmlのソース表示&コピー

アドオンパネルにpugとhtmlのソースを表示することができます。
※自作のpugパネルはホットリロードが効きません。変更確認したい場合はリロードしてください。

pugパネルへのソース追加方法

【.stories.pug】で追加されたストーリー → 自動的にパネルに追加されます
【.stories.js】で追加するストーリー → parametersの【pugCode】に/stories/以下のパスを入れる


//csf
export const Default = () => {/省略/}
Default.story = {
  parameters:{pugCode:'Examples/Media/Media.pug'}
}

//storiesOf
storiesOf('Examples/Media',modules)
.add('Media', () => {/省略/},
{pugCode:'Examples/Media/Media.pug'})

Pugのmixinで作成するコンポーネント

pugのmixinを使用することでstorybookの形に合うコンポーネント作成をすることが出来ます。

静的なHTMLのためのコンポーネント駆動開発の記事が参考になると思います。
DEMOにもこちらの記事の動作サンプル(テスト以外)を入れてあります。

リンクボタンの作成サンプル

大中小サイズ、横幅フルサイズ、色、URL、外部リンクの設定ができるコンポーネントをpugのmixinで作成します。
paramsの設定で切り替わるような仕組みになります。

/stories/Components/LinkButton/LinkButton.pug
mixin LinkButton(params={})
  - const props = Object.assign({ url: '' ,full:false}, params) //デフォルトのパラメータ

  - let className = attributes.class !== undefined ? attributes.class : ''
  - if(props.size) className += ' LinkButton--' + props.size
  - if(props.full) className += ' LinkButton--full'
  - if(props.color) className += ' LinkButton--' + props.color
  - if(props.isBlank) Object.assign( attributes , {'target':'_blank'})
  - const attrs = Object.assign( attributes , {class:className})
  a.LinkButton(href=props.url)&attributes(attrs)
    block
/stories/Components/LinkButton/LinkButton.styl
.LinkButton
  padding 10px 50px
  text-decoration none
  color #000000
  position relative
  text-align center
  border 1px solid #CCCCCC
  border-radius 5px
  font-size 16px
  display inline-flex
  justify-content center
  align-items center
  box-sizing border-box

  /* サイズ */
  &--small
    padding 5px 50px
    font-size 12px

  &--large
    font-size 24px

  /* フルサイズ */
  &--full
    width 100%

  /* カラー */
  &--gray
    background #8c9094
    border 1px solid #8c9094
    color #ffffff

  &--green
    background green
    border 1px solid #FFF
    color #ffffff

こんな感じmixinを作ると【.stories.pug】では、コンポーネントベースのコードで書くことが出来ます。
knobsまで作らなくても色々なパターンを作成しておけば、コピー用サンプルやコンポーネントを修正した際の見た目のテストみたいな使用も可能です。

/stories/Components/LinkButton/サンプル.stories.pug
include LinkButton
p
  +LinkButton({
  })
    | ノーマル
p
  +LinkButton({
    size:'small',
    color:'green',
  })
    | 緑小
p
  +LinkButton({
    size:'large',
    color:'gray',
    url:'https://google.com',
    isBlank:true
  })
    | グレー大
p
  +LinkButton({
    size:'small',
    full:true,
  })(class="addClass")
    | 小フルサイズ

mixin_sample.jpg

knobsを書くJSサンプル

今のコンポーネントをKnobs化するサンプルです。

/stories/Components/LinkButton/LinkButton.stories.js
import { withKnobs, boolean, select ,text} from '@storybook/addon-knobs'
import { renderer } from 'storypug'
import LinkButton from './LinkButton.pug'
const { html } = renderer()

const sizes = {
  'ノーマルボタン':'',
  '小さいボタン':'small',
  '大きいボタン':'large',
}
const colors = {
  'デフォルト':'',
  'グレー':'gray',
  'グリーン':'green',
}

export default {
  title: 'Components/LinkButton',
  decorators: [withKnobs],
}

// knobs
export const Knobs = () =>
html(
  LinkButton,
  {
    size: select('ボタンタイプ', sizes, sizes[0]),
    full: boolean('フルサイズ', false),
    color: select('', colors, colors[0]),
    url: text('URL',''),
    isBlank: boolean('別窓', false),
  },
  'ボタンテキスト',
)
Knobs.story = {
  parameters:{pugCode:'Components/LinkButton/LinkButton.pug'}
}

knobs_sample.jpg

ビルドについて

githubpagesとテスト環境にそれぞれ作成したいというようなケースのために、ビルド設定を二つ用意しています。

  • .storybook/default → 【npm run build】 元の設定と同様publicフォルダを設定しています。
  • .storybook/second → 【npm run build2】 githubpagesを想定してdocsフォルダを設定しています。

.storybook/defaultをコピーしてpackage.jsonのscriptsを修正すれば、さらに複数作ることも可能です。
staticフォルダも元の設定と同様staticなのでメイン環境などと合わせる場合は、この辺も調整してください。

ビルドにおけるpugの共通変数の設定

ファイルを置くパスが違うケースもあると思うので、それぞれの環境にpugの共通変数用としてpug-data.jsに変数をセットする仕組みを用意しています。
通常layout.pugなどに設定するような変数をここにセットすることで、コンポーネントを修正せずに出し分けすることができます。
【stories.pug】による自動追加でも、この共通変数が一緒にセットされます。

pug-dataの使い方

先ほど作成したLinkButtonを使用して、外部リンク設定時にアイコンのimgタグを表示するように変更してみます。

1 画像フォルダの共通変数を設定

/.storybook/default/pug-data.js
//pug common values
module.exports = {
  imgDir:"/images/"
}

2 LinkButton.pugコンポーネントの【block】の下にblankのif文を追記

/stories/Components/LinkButton/LinkButton.pug
  a.LinkButton(href=props.url)&attributes(attrs)
    block
    -if(props.isBlank)
      img(src=imgDir + 'icon-blank.png' width="16px" style="margin-left:10px")

3 LinkButton.stories.jsの【renderer()】の行をpug-data.jsを読み込むように修正

/stories/Components/LinkButton/LinkButton.stories.js
import pugData from '@conf/pug-data'
const { html } = renderer(pugData)

別窓チェック時に共通変数で設定する画像アイコンが表示できるようになります。
blank画像.jpg

このpug-dataの共通変数と同名の変数を本プロジェクトのlayout.pugに作成すれば、コンポーネント開発はstorybook上でやりつつ、本プロジェクトの環境はincludeで使用していく同一ソース運用もできるかと思います。
package.jsonのbuild設定でoutputやstaticの場所少しいじれば、比較的簡単に今お使いの開発環境と連携できると思うので色々お試しください。

16
12
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
16
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?