手摸手教你用 Storybook 改善元件庫的開發

江米小棗tonylua發表於2019-05-11

在上一篇文章 《手摸手教你封裝跨專案複用的 Vue 元件》 中,介紹了一例用 rollup.js 封裝 Vue.js 元件庫的實踐;限於篇幅和複雜度,其中元件的即時除錯預覽部分,也同樣採用了 rollup 一併配置出來,雖然完全夠用,但執行起來稍嫌麻煩,bigger 上感覺也差強人意。

本篇的內容就是嘗試優化這部分的開發體驗,用業界成熟的解決方案 Storybook 解決元件的統一展示和事實除錯。

更快更強的構建 UI 元件
Storybook 是一個為開發獨立的 React、Vue 和 Angular UI 元件的開源工具。高效有序地構建炫酷使用者介面

以上是官網開宗明義的介紹,總之在 React 等領域,Storybook 已經很好的證明了自己,引入這個工具以後,即便是在普通的專案中,也能幫助開發者逐漸打理出各種低耦合的可複用元件;如果搭配 Lerna 等工具,甚至直接把元件分別釋出到 npm 上也能安排的妥妥的。

因為是承接上一篇的內容,所以本文就不展開介紹 Storybook 的種種細節,反正用它做的事情和我們之前已經做過的是一樣的:實時編譯除錯、手動測試執行。

基於之前的專案,直接說明改動步驟。

首先,引入 Storybook 後專案結構將微調成這樣:

├─.babelrc
├─.eslintignore
├─.eslintrc.js
├─.gitignore
├─jest.config.js
├─package.json
├─postcss.config.js
├─rollup.config.js
├─CHANGELOG.md
├─README.md
├─dist/
├─node_modules/
├─src/
├─.storybook/
├─storybook-static/
├─__mocks__/
└─__tests__/
複製程式碼

其中,可見以下兩個資料夾:

├─.storybook/
├─storybook-static/
複製程式碼

分別用來存放配置和生成的靜態預覽頁面。

要設定 Storybook 環境,需要先安裝必要的依賴:

npm install @storybook/vue --save-dev
npm install vue-loader style-loader css-loader sass-loader node-sass --save-dev
複製程式碼

執行初始化:

npx -p @storybook/cli sb init --type vue
複製程式碼

此時會自動增加兩個 npm scripts:

"scripts": {
    ...
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
},
複製程式碼

刪除預設生成的資料夾:

rm -rf ./stories/
複製程式碼

修改 .storybook/config.js 中的相應配置,直接把 .stories.js 檔案和對應的元件原始碼放在一起:

const req = require.context('../src', true, /\.stories\.js$/);

...
複製程式碼

同樣在以上檔案中,做一些和專案中 main.js 相似的初始化工作:

// .storybook/webpack.config.js

import 'normalize.css';
import Vue from 'vue';
import Element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(Element);

...
複製程式碼

為了正確解析 Vue 單檔案元件中的樣式部分,修改設定:

// .storybook/webpack.config.js

const path = require('path');

module.exports = async ({ config, mode }) => {
  config.module.rules.push({
    test: /\.scss$/,
    include: path.resolve(__dirname, '../src'),
    use: ['style-loader', 'css-loader', 'sass-loader'],
  });
  return config;
};
複製程式碼

在 .storybook/preview-head.html 中引入必要的樣式等,專案中的類似工作可能是在 index.html 等處完成的:

<link rel="stylesheet" href="//foo/bar/index.css">
複製程式碼

接下來就是動手編寫各種元件的 story 用例,比如:

// src\projectA\components\HorizentalRadios.stories.js

import { storiesOf } from '@storybook/vue';
import HorizentalRadios from './HorizentalRadios';

storiesOf('projectA|超過個數變成下拉的raidos', module)
  .add('列表少於預期個數時', () => ({
    components: { HorizentalRadios },
    template: `<horizental-radios
      v-model="value"
      @change="valueChange"
      :max-shown-count="3"
      :items="items"
      item-label="label"
      item-name="name"
      more-label="更多的呢"
      :list-style="false" />`,
    data() {
      return {
        value: 'aaa',
        items: [{
          label: 'aaa',
          name: 'name1'
        }, {
          label: 'bbb',
          name: 'name2'
        }],
      };
    },
    methods: {
      valueChange() {
        console.log(this.value);
      },
    },
  }))
  .add('列表多於預期個數時+列表主題色', () => ({
    components: { HorizentalRadios },
    template: `<horizental-radios
      v-model="value"
      @change="valueChange"
      :max-shown-count="3"
      :items="items"
      item-label="label"
      item-name="name"
      more-label="更多的呢"
      :list-style="true" />`,
    data() {
      return {
        value: 'aaa',
        items: [{
          label: 'aaa',
          name: 'name1'
        }, {
          label: 'bbb',
          name: 'name2'
        }, {
          label: 'ccc',
          name: 'name3'
        }, {
          label: 'ddd',
          name: 'name4'
        }, {
          label: 'eee',
          name: 'name5'
        }, {
          label: 'fff',
          name: 'name6'
        }],
      };
    },
    methods: {
      valueChange() {
        console.log(this.value);
      },
    },
  }))
複製程式碼

可見對同一個元件,可以 add 多個用例,這點和單元測試時的做法很相似;

同時 storiesOf() 類似於單元測試的 describe() 部分,並且其第一個引數可以用 | 分割,表示層級。

執行 npm run storybook 檢視效果:

手摸手教你用 Storybook 改善元件庫的開發

最後釋出前不要忘記 npm run storybook,生成靜態頁面,以便其他開發者可以直接執行檢視。

手摸手教你用 Storybook 改善元件庫的開發



--End--

手摸手教你用 Storybook 改善元件庫的開發

搜尋 fewelife 關注公眾號

轉載請註明出處

相關文章