動機
reactのcomponentをstorybookで開発しようと思ったが、storybookの解説ではnodeのwebserver機能を使っていて腑に落ちないので私の大好きなnginxに置き換えたかった。動かすまでが仕事。
やってみる
バージョン
- Docker for Mac:1.12.5 (14777)
- npm:3.10.10
- node:v7.3.0
storybookとreactのインストール
Slow Start Guideを見ながら準備します。
想定しているディレクトリ構成
.
├── node_modules
├── out
├── package.json
├── stories
│ └── index.js
├── storybook
│ └── config.js
└── web
└── Dockerfile
まずはインストール
npm init
npm install --save-dev @kadira/storybook
npm install --save react react-dom
次にSlow Start Guideのサンプルをそのままコピペ。
stories/index.js
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
storiesOf('Button', module)
.add('with text', () => (
<button onClick={action('clicked')}>Hello Button</button>
))
.add('with some emoji', () => (
<button onClick={action('clicked')}>😀 😎 👍 💯</button>
));
storybook/config.js
import { configure } from '@kadira/storybook';
function loadStories() {
require('../stories/index.js');
// You can require as many stories as you need.
}
configure(loadStories, module);
Dockerの準備
使うのはnginx:alpineイメージです。
web/Dockerfile
FROM nginx:alpine
docker-composeは以下のような設定してlocalhost:8080/out/で確認します。
ポイントはvolumesで出力先ディレクトリの親ディレクトリを指定しているところです。
docker-compose.yml
version: '2'
services:
web:
build: ./web
ports:
- "8080:80"
volumes:
- ".:/usr/share/nginx/html"
npm scriptsの設定
最後にExporting Storybook as a Static Appを見ながらnpmのscriptsを設定します。storybookディレクトリのconfig.jsを参照して、outディレクトリに成果物を生成する設定です。
package.jsonの抜粋
"scripts": {
"storybook": "build-storybook -c ./storybook -o ./out",
"test": "echo \"Error: no test specified\" && exit 1"
},
ここまで終わったら
docker-compose up
npm run storybook
で好きなタイミングで生成してhttp://localhost:8080/out/
(要スラッシュ)にアクセスすればOKです。
注意点
- build-storybookの-oオプションで指定したディレクトリは実行の都度削除して作り直すという動作します。-oオプションで指定したディレクトリをvolumesでマウントするとbuildごとにinodeが変更されてしまい、正しくマウントできません。そのためその親ディレクトリをマウントしています。以下のようなコード(抜粋)が実行されています。
react-storybook/src/server/build.js
// create output directory (and the static dir) if not exists
shelljs.rm('-rf', outputDir);
shelljs.mkdir('-p', path.resolve(outputDir));
shelljs.cp(path.resolve(__dirname, 'public/favicon.ico'), outputDir);
- nginx側のセキュリティとか全く考慮してないので、公開ディレクトリなどはきちんと設定した方が気持ちいいと思います。outディレクトリだけ公開するとか。
参考
Slow Start Guide
Exporting Storybook as a Static App
React Storybook入門:コンポーネントカタログがさくさく作れちゃうかもしれないオシャレサンドボックス環境
React Storybook で変わるUI開発フロー (Redux Flavor)