腦袋疼的react組件可視化

想搞個組件可視化好久了,一開始就是想作個和antd相似的,而後就遇到了一系列的問題javascript

組件可視化的目的:css

  1. 歷史組件可感知,可以作到信息同步
  2. 可以改變開發流程,可以提早進行組件的視覺驗收
  3. 便於後期的視覺規範統一

Q1:如何搞個和antd相似的組件庫?

調研發現,antd使用的是阿里系的bisheng這個包vue


Q2:bisheng的解決的問題是?

目的是將markdown轉成靜態站點,antd就是這樣產生的java


Q3:bisheng存在的問題?

  1. 好久無人維護,文檔更新等都比較滯後
  2. 且文檔比較難讀,上手比較麻煩

Q4:除了bisheng市面上還有什麼解決方案?

這就是本次要說的storybook了,目前3.7w個star,且生態比較好,插件也很多react


Q5:storybook怎麼上手?

step1:安裝依賴

npm init -y
npm install @storybook/react --save-dev
npm install react react-dom --save
npm install babel-loader @babel/core --save-dev 
複製代碼

step2:添加script腳本

在package.json中添加webpack

{
 "scripts": {
   "storybook": "start-storybook"
 }
}
複製代碼

step3:添加config文件

建立.storybook/config.js文件git

import { configure } from '@storybook/react';

function loadStories() {
  require('../stories/index.js');
  // 能夠添加多個store
  // You can require as many stories as you need.
}

configure(loadStories, module);
複製代碼

step4:開始寫story

建立../stories/index.js文件github

import React from 'react';
import { storiesOf } from '@storybook/react';
import { Button } from '@storybook/react/demo';

storiesOf('Button', module)
  .add('with text', () => (
    <Button>Hello Button</Button>
  ))
  .add('with emoji', () => (
    <Button><span role="img" aria-label="so cool">😀 😎 👍 💯</span></Button>
  )); 
複製代碼

step5:跑起來

npm run storybook
複製代碼

效果

image.png

  • ok,成功搞定,已經可以看到編寫的代碼了

總結:storybook按照配置,跑起來仍是比較輕鬆的


Q6:如何設計目錄結構?

官方提供了三種,我選擇了我的認爲比較清晰的方式
web

image.png

  1. button.js是組件代碼
  2. button.stories.js是故事代碼

按照上面的設計估計應該就可以知足咱們的需求了chrome


Q7:如何按需加載?

只是簡單配置可不行,若是不在一開始就搞好的話,隨着後面業務的擴展會帶來不少問題,像按需加載這種功能仍是一開始就設計比如較好

修改.storybook/config.js

import { configure } from '@storybook/react';

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

function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
複製代碼

Q8:storybook插件是什麼?

  1. 前面有了組件庫展現,但距離可查看api、可測試、可調整樣式等差距還很大
  2. 這些額外的功能就須要添加依賴來解決了
  3. 在storybook中插件概念叫作 addons

Q9:啥是addons?

  1. addons是添加的意思
  2. 在storybook則用來將其用做表示增長的功能

**
重要的事情說三遍:

在.storybook配置文件中,添加一個addons.js文件
**在.storybook配置文件中,添加一個addons.js文件
**在.storybook配置文件中,添加一個addons.js文件

addons.js文件是用來維護插件的配置文件

image.png


Q10:如何體驗第一個addons?

image.png

官網上Addons目錄就是官方推薦的插件列表,開始一個個嘗試


Q11:什麼是addons-knobs?

image.png

這個可就牛逼了,knobs主要是用來提供動態調整交互的能力,實踐一下

step1:安裝依賴

npm i @storybook/addon-knobs -D 
複製代碼

step2:添加配置項

找到.storybook/addons.js在其中添加一句話

import '@storybook/addon-knobs/register';
複製代碼

step3:修改已有的stories

按照github地址,添加示例代碼

import React from 'react';
import { storiesOf } from '@storybook/react';
import { withKnobs, text, boolean, number } from '@storybook/addon-knobs';

const stories = storiesOf('Storybook Knobs', module);

// Add the `withKnobs` decorator to add knobs support to your stories.
// You can also configure `withKnobs` as a global decorator.
stories.addDecorator(withKnobs);

// Knobs for React props
stories.add('button', () => (
  <button disabled={boolean('不可用', false)} > {text('文案', '牛逼的knobs')} </button>
));

// Knobs as dynamic variables.
stories.add('as dynamic variables', () => {
  const name = text('Name', 'Arunoda Susiripala');
  const age = number('Age', 89);

  const content = `I am ${name} and I'm ${age} years old.`;
  return (<div>{content}</div>);
});
複製代碼

上面一共作了幾件事情:

  1. 在stories上添加了一個修飾器
  2. 在button上添加了對屬性的包裝,例如text()、boolean()等至關於對屬性進行了綁定

直接看效果

step4:雙向綁定效果

image.png

能夠看到,咱們訂閱的兩個數據類型已經顯示在了Knobs中了,此時修改內容,組件內容也隨之改變
image.png

step5:計算屬性

上面例子中,第二個case,包含計算變量

// Knobs as dynamic variables.
stories.add('as dynamic variables', () => {
  const name = text('Name', 'Arunoda Susiripala');
  const age = number('Age', 89);

  const content = `I am ${name} and I'm ${age} years old.`;
  return (<div>{content}</div>);
});
複製代碼

image.png

當修改age後,也會從新渲染
image.png

Knobs極其強大:

  1. 這個計算屬性,很像vue中的computed屬性,當數據改變便可以改變交互
  2. 同時也能夠快速驗證多種狀態
  3. 也能夠快速驗證邊界狀況

Q12:什麼是addons-actions

image.png

Actions用來獲取用戶點擊信息,這個具體使用暫時沒太想到場景,看了demo,目前是用來區分具體點擊的位置

step1:安裝依賴

npm i -D @storybook/addon-actions
複製代碼

step2:修改.storybook/addons.js

import '@storybook/addon-actions/register';
複製代碼

step3:綁定單個事件

import { storiesOf } from '@storybook/react';
import { action, configureActions } from '@storybook/addon-actions';

import Button from './button';

storiesOf('Button', module).add('default view', () => (
  <Button onClick={action('button-click')}>Hello World!</Button>
));
複製代碼

step4:綁定多個事件

import { storiesOf } from '@storybook/react';
import { actions } from '@storybook/addon-actions';

import Button from './button';

// This will lead to { onClick: action('onClick'), ... }
const eventsFromNames = actions('onClick', 'onMouseOver');

// This will lead to { onClick: action('clicked'), ... }
const eventsFromObject = actions({ onClick: 'clicked', onMouseOver: 'hovered' });

storiesOf('Button', module)
  .add('default view', () => <Button {...eventsFromNames}>Hello World!</Button>)
  .add('default view, different actions', () => (
    <Button {...eventsFromObject}>Hello World!</Button>
  ));
複製代碼

Q13:什麼是addons-storysouce

image.png

這個理解起來仍是相對簡單的,目的就是在控制檯中顯示故事源

step1:安裝依賴

npm i  @storybook/addon-storysource --dev
複製代碼

step2:建立webpack.config.js

module.exports = function({ config }) {
  config.module.rules.push({
    test: /\.stories\.jsx?$/,
    loaders: [require.resolve('@storybook/addon-storysource/loader')],
    enforce: 'pre',
  });

  return config;
};
複製代碼

這個和前面兩個插件不一樣之處就在這,它須要在webpack中添加一個loader,經過storybook自己的webpack對外暴露,對其添加插件

step3: 查看源碼效果

image.png


Q14:什麼是addon-info?

image.png

這個info插件也十分強大,可以快速將組件中的配置信息,轉換成markdown可閱讀模式中組件信息

step1:安裝依賴

npm i -D @storybook/addon-info
複製代碼

step2:添加插件

addon-info採用的是修飾器模式,能夠全局添加,也能夠局部添加

  1. 全局修飾就是在config中全局添加
addDecorator(withInfo); // Globally in your .storybook/config.js.
複製代碼
  1. 局部修飾的花,就在stories中添加
storiesOf('Component', module)
  .addDecorator(withInfo) // At your stories directly.
  .add(...);
複製代碼

step3:在組件代碼中添加propTypes

import React from 'react';
import PropTypes from 'prop-types';
const Test = (props)=><div>{props.children}</div>
Test.propTypes = {
  text: PropTypes.string.isRequired,
  onDelete: PropTypes.func,
}
export default Test
複製代碼

添加addons-info插件後,就會增長showinfo按鈕

image.png

點擊showinfo,就可見
image.png

  1. 自動將組件名稱轉爲了markdown
  2. 自動將組件代碼轉爲了markdown
  3. 自動將propsTypes轉爲了表格

不過表格中的信息仍是有丟失,缺乏默認值、描述

step4:在組件代碼中添加默認值、描述

import React from 'react';
import PropTypes from 'prop-types';
const Test = (props)=><div>{props.children}</div>
Test.defaultProps = {
  text: '默認值',
  onDelete: () => {}
};
Test.propTypes = {
   /** 這裏text是註釋 */
  text: PropTypes.string.isRequired,
  /** 這裏onDelete是註釋 */
  onDelete: PropTypes.func,
}
export default Test
複製代碼
  1. 默認值經過defaultProps設置
  2. 註釋經過在屬性上添加註釋來實現

image.png


Q15:什麼是addon-viewport?

viewport你們都很熟悉,這個就是用來搞移動端的

step1:安裝依賴

npm i --save-dev @storybook/addon-viewport
複製代碼

step2:註冊插件

在.storyboos/config中註冊

import '@storybook/addon-viewport/register';
複製代碼

step3:全局添加

import React from 'react';
import { configure,addDecorator,addParameters } from '@storybook/react';
// config.js
import { withInfo } from '@storybook/addon-info';
addDecorator(withInfo);
addParameters({
  viewport: { defaultViewport: 'iphone6' },
});

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

function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
複製代碼

這裏就是使用addParameters方法,很方便就能夠

image.png

這樣默認就有了一批viewpoint,這一塊具體配置,就慢慢讀文檔就行了


Q16:什麼是addons-shots

這部分是測試用例相關,短期內啃不下來,待後面有時間再補充

image.png


Q17:什麼是addon-backgrounds

image.png

這個主要是用來設置背景色,非必須,無關緊要


Q18:什麼是addon-a11y

image.png

這個至關與lint類的功能,在實際項目中仍是頗有用的

step1:安裝依賴

npm i @storybook/addon-a11y --dev
複製代碼

step2:註冊插件

修改addons

import '@storybook/addon-a11y/register';
複製代碼

step3:添加修飾器和參數

在config文件中添加

addDecorator(withA11y);
addParameters({
  a11y: {
    // ... axe options
    element: '#root', // optional selector which element to inspect
    config: {}, // axe-core configurationOptions (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#parameters-1)
    options: {} // axe-core optionsParameter (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter)
  },
});

複製代碼

ok,這樣的話,若是書寫不符合規範的按鈕,則會報錯

image.png


Q19:什麼是addon-console

image.png

前面不少插件,添加了不少信息到操做臺上,因此不少人容易忽略掉chrome控制檯內部的信息,因此這個插件頗有意義,就是用來把控制檯的信息映射到操做臺上,具體配置也比較簡單,按照文檔操做便可


Q20:什麼是addon-links

image.png

這個插件解決的問題是,story之間的相互跳轉,用法也很簡單,只須要參考文檔就好


Q21:除了這些官方推薦插件外還有哪些?

目前比較好的插件列表以下

  1. Storyshots: 快照測試。
  2. Specs: 交互測試。
  3. Notes: 在 story 中添加備註。
  4. Info: 用於建立 css 框架手冊。
  5. Readme: 將 markdown 導入爲 story。
  6. actions: 顯示事件的 event 對象。
  7. Intl: 添加 locales 面板,用於切換語言。
  8. State: 添加 state 面板,展現或更新 state,重繪視圖。
  9. Props Combinations: 配置可能有的props,一次性繪出多個組件做對比。
  10. Knobs: 頁面上變動 props 重繪視圖。
  11. Links: 經過 linkTo 函數或 LinkTo 組件連接多個 story,支持點擊跳轉。
  12. Story-router: 裝飾器,支持 storybook 使用 react-router 等路由組件。
  13. Backgrounds: 切換背景圖或背景顏色。
  14. i18n tools: 切換文字對齊方式,左對齊或右對齊。
  15. Material-UI: 添加並切換自定義主題。
  16. Host: 裝飾器,在頁面上以盒模式展現組件。
  17. Chapters: 在同一個 story 中以章節形式展現多個組件。
  18. Options: 調整 storybook 頁面外觀,切換爲全屏等。
  19. Console: 將瀏覽器控制檯 console 信息輸出到 storybook log 面板。
  20. JSX preview: 展現及拷貝 JSX 代碼。
  21. Versions: 添加版本號,查看各版本的變化。
  22. Apollo: 添加 Apollo client,模擬 GraphQL 查詢。
  23. Screenshot: 保存網頁截圖。
  24. Styles: storybook 預覽界面添加自定義樣式。
  25. Figma: 添加 Figma 設計面板。

Q22:總結有哪些?

  1. 最爽的點:若是storybook直接扔進項目裏,能夠共享一套webpack配置,且組件在業務中和story中可以同時同步,實時同步
  2. 解決的問題:
  3. storybook主要解決的是歷史組件的展現
  4. 也可改變驗收流程,先進行組件驗收,再進行業務驗收
  5. 同時也有利於新同窗上手
  6. 設計劃分:
  7. 第一階段:先把storybook集成在一塊兒,便於提高效能
  8. 第二階段:提取成熟組件,到公共層面,便於其餘項目使用
  9. 第三階段:組件和story分離,變成兩個項目維護,保持組件純淨,story做爲文檔解決方案

Q23:待辦有哪些?

  1. 在showinfo中展現組件
  2. 自定義markdown中的表格樣式
  3. 添加測試用例的開發(addons-shots)
  4. background添加顏色

Q24:參考有哪些?

  1. storybook使用指南
  2. storybook官網
相關文章
相關標籤/搜索