TOC
簡介
- 響應式 UI 開發及測試環境
- 可有效提高組件的可重用性、可測試性和開發速度
- 可以快速構建,而無需擔心應用程序特定的依賴
目錄結構
.
├── .storybook
│ ├── config.js # storybook 進入點
│ └── webpack.config.js # 客製化 webpack 打包 for storybook
├── stories # 各種想說的故事
│ ├── comp-a
│ ├── ...
│ └── comp-z
├── storybook-static # storybook gen 出來的 dist 資料夾
├── db.json # mock api 設定
├── routes.json # restful 路由處理
└── package.json # 新增 storybook 的 script
運作流程
其實 storybook 等於是另外打包同專案成另一個 APP 介面
- storybook 啟動時會先以
.storybook/config.js
為進入點 - 執行
loadStories()
依照設定批次載入故事腳本 - 進行 storybook 自身的 wepback 打包
- 如有額外需求需在
.storybook
資料夾下新增webpack.config.js
- 如有額外需求需在
- 以 server 形式啟動 dashboard
安裝建置
已導入既有專案為例
初始化安裝
npx -p @storybook/cli sb init --type html
安裝 storybook 相依工具 (babel 是為了 storybook 打包而裝的)
yarn add -D @storybook/html babel-loader @babel/core
加入下列指令至
package.json
的 scripts 欄位底下{ "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook", }
- storybook 的 config 檔
import { configure } from '@storybook/html'; import '../src/scss/main.scss'; function loadStories() { const myDOM = document.createElement('div'); myDOM.className = 'bg'; myDOM.style.cssText = 'margin-top: 200px; display: flex; justify-content: center; align-items: center;'; require(`../stories/a.js`); require(`../stories/b.js`); require(`../stories/c.js`); } configure(loadStories, module);
storybook 的 webpack.config.js
const path = require('path'); module.exports = async ({ config, mode }) => { config.module.rules.push({ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'], include: path.resolve(__dirname, '../'), }); return config; };
- mock 一個
json-server
- 為了要模擬 API 藉以避免頁面壞掉
- 開一個
db.json
在專案目錄下 - 開一個
routes.json
指定 restful 路徑
說故事
已新增一個
推播泡泡
為例- 可看得出來
createDOM
負責把基本 dom 搭建出來 - 需要用 setTimeout 克服非同步問題
- 由以下 js 可見可以為一個元件設置不同狀態
import { storiesOf } from '@storybook/html'; import { createDOM } from './init.js'; import Toast from '../src/js/component/Toast.js'; const showToast = ({ text, num }) => { window.setTimeout(( () => { const Toast = new Toast(); Toast.render( Toast.setVal( text, num ) ); }), 0); }; storiesOf('Toast', module) .add('普通版', () => { const initDOM = createDOM(); showToast({ text: "歡迎回來", num: 1 }); return initDOM; }) .add('浮誇版', () => { const initDOM = createDOM(); showToast({ text: "哇嗚~~ 大大您回來啦 LA LA LA~~~", num: 1 }); return initDOM; });
- mock 一個
注意事項
div.insertAdjacentHTML( 'beforeend', str );
- 可以把 html text 注入到指定 div
storybook 吃的 webpack 設定是在
.storybook
底下- 在此資料夾外怎麼設定都是沒用的喔
遇到問題
ERROR in ./.storybook/config.js Module build failed (from ./node_modules/babel-loader/lib/index.js): Error: [BABEL] /pathto/.storybook/config.js: You gave us a visitor for the node type PrivateName but it's not a valid type (While processing: "pathto/plugin-proposal-class-properties/lib/index.js")
- 原因
- babel 版本太舊
"@babel/core": "^7.0.0-beta.42",
- 解法
- 升到 “@babel/core”: “^7.0.0-beta.47”,
- 原因
Uncaught (in promise) TypeError: Cannot read property 'insertAdjacentHTML' of null
- 要用 setTimeout 往後延遲
參考連結
- 請 Toby 喝珍奶,你請我就喝 -
YA~大杯還小杯~看你誠意 ❤ ️
使用手機掃描 QRCODE 完成 pay 下去就對