前情提要
不論是 App 或是 Web, 與使用者第一線互動的就是 UI 了。
另一面在需求設計上, 我們總會想像一個畫面,
想像著使用者如何使用我們的產品,
也就是說 UI 是理想與真實的邊界。
Designer 完成了設計, Engineer 將之實作出來,
主流的開發方式會透過 Component 來節省時間。
為什麼我們需要 Storybook ?
但是真的能節省時間嗎 ?
開發人員彼此之間會不會重複造輪子? 他們又要怎麼溝通?
修改到底層元件會不會影響到上層元件? 會不會改 A 壞 B?
複雜的 Component, 特殊的情境如何測試 ?
Storybook 恰恰能解決這些問題,
- 作為開發人員的指南和文件
- 獨立於應用程式建立 Component
- 測試特殊情境
對我來說,最重要的事,我可以用類似 TDD 的方式開發,
在 Storybook 的官方文件提到這個方法為 CDD.
在 TDD 中我們把一個個 Use Case 寫成 Test Case,
我們可以挪用這個觀念,
在 Storybook 中把每一個 Component 的各種狀態(State),
當作 Use Case, 然後透過 Mock State 讓 Component 呈現該有的樣貌。
心得
大前端的時代,僅僅只看 Web 的話,
我認為這個時代前端的重心就在兩個主要的技術之上,
Component 與 State Management。
而實作你可以有以下的選擇,
僅介紹我聽過的主流 Library,
Component 與 State Management 沒有絕對的搭配關係。
| Component | State Management |
|---|---|
| React | Flux |
| Angular | Redux |
| Vue | Akita |
改編 Storybook 教程
為什麼要改編 Storybook 教程(React Version) ?
這個教程會以一個簡單的 Todo List,
從創建應用程式、簡單的 Component 到複雜,
與狀態管理器介接, 測試到部署。
但是他缺了一味,TypeScript,
所以我自已用 TypeScript 進行了改寫並稍作一下記錄。
環境
- 作業系統 : Windows 10 Pro
- 瀏覽器 : Chrome
開始
設定初始化的環境
設定 React Storybook
開啟命令提示視窗,執行以下命令以創建 React App
1 | # Create our application: |
安裝 Storybook
1 | npm i storybook |
啟動開發環境的 Storybook,
1 | # Start the component explorer on port 6006: |
測試與執行
1 | # Run the test runner (Jest) in a terminal: |

下載 CSS,存檔至 src/index.css
安裝 degit
1 | npm i degit |
加入 Add assets (字型與 Icon)
1 | npx degit chromaui/learnstorybook-code/src/assets/font src/assets/font |
Git Commit
1 | > git add . |
簡單的 component
在 src/components/ 資料夾建立 component Task.js
1 | // src/components/Task.js |
建立 Task.stories.js
1 | // src/components/Task.stories.js |
隨時你都可以執行 yarn storybook 試跑來看看 storybook
調整 Storybook 的 config 檔 (.storybook/main.js)
1 | // .storybook/main.js |
(.storybook/preview.js) 這設定為了 log UI 上的某些操作產生的事件,
在之後我們會看到 完成(onArchiveTask)或置頂(onPinTask) 兩個事件
1 | // .storybook/preview.js |
調整 Task.js
1 | // src/components/Task.js |
加入測試用的外掛(add on)
1 | yarn add -D @storybook/addon-storyshots react-test-renderer |
執行測試
1 | > yarn test |
測試結果
1 | yarn run v1.22.0 |
簡單的 component 改用 typescript
首先,Task.js 調整副檔名為 Task.tsx,Task.stories.js 為 Task.stories.tsx.
測試檔案 storybook.test.js 也一併修改 storybook.test.ts
並修改 .storybook/main.js
1 | module.exports = { |
建立 tsconfig.json 檔
1 | > tsc --init |
用 TypeScript 改寫
1 | // src/components/Task.tsx |
改寫 Task.store.tsx
1 | // src/components/Task.stories.tsx |
組合成複雜的 component (TypeScript 版本)
與教程最主要的不同之處在於使用了 TypeScript 的語法撰寫
1 | // src/components/TaskList.tsx |
TaskList.stories.tsx 設置,也是使用 TypeScript 撰寫。
1 | // src/components/TaskList.stories.tsx |
介接 Store 資料
建立 Redux
1 | // src/lib/redux.ts |
修改 TaskList.tsx 視作一個 container 與 redux 作介接:
1 | // src/components/TaskList.tsx |
加上 Page InboxScreen
1 | //src/components/InboxScreen.js |
一樣也加上 Story ,InboxScreen.stories.tsx
讓我們可以透過 Storybook 作人工 E2E 測試
1 | //src/components/InboxScreen.stories.tsx |
完整代碼可以參考此處。
參考
- Learn Storybook(javascript version)
- React+TypeScript Cheat sheets
- Component Library
- State Management Library
(fin)









頁面。](/images/2020/10/email/gmail_application_setting.jpg)
頁面。](/images/2020/10/email/gmail_application_add.jpg)


