如何開發React UI元件庫

萬小萬發表於2019-05-11

github.com/onfuns/wui

技術棧:React + Webpack + TypeScript + Docz

先上腳手架目錄結構

如何開發React UI元件庫

  • docz:docz文件生成器的配置目錄
  • example:demo目錄
  • lib:打包後生成檔案目錄
  • scripts:執行指令碼目錄
  • src:測試、元件、文件目錄

注意:本腳手架只是基本配置,內部程式碼比較簡潔,主要是起到一個學習引導作用。

元件開發過程中沒什麼技術難點,主要是樣式處理。 全域性default.less樣式處理借鑑了antd,將常用的樣式用變數儲存,方便後續主題設定

@wui-prefix: wui;

@primary-color: red;
@info-color: #3bb4f2;
@success-color: #5eb95e;
@danger-color: #dd514c;
@warning-color: #f37b1d;
@white: #fff;
@black: #000;

@alert-info-bg-color: @info-color;
@alert-success-bg-color: @success-color;
@alert-warning-bg-color: @warning-color;
@alert-danger-bg-color: @danger-color;
複製程式碼

mixins/alert.less混合用函式注入變數

.var-alert(@background-color, @border-corlor, @text-color) {
  border: 1px solid @border-corlor;
  background-color: @background-color;
  color: @text-color;
}

複製程式碼

然後元件components/alert/index.less中直接引入即可

@import '../style/default.less';
@import '../style/mixins/alert.less';

@alert-prefix-cls: ~'@{wui-prefix}-alert';

.@{alert-prefix-cls} {
  position: relative;
  padding: 8px 16px;
  margin-bottom: 10px;

  &-info {
    .var-alert(@alert-info-bg-color, @alert-info-bg-color, @white);
  }

  &-success {
    .var-alert(@alert-success-bg-color, @alert-success-bg-color, @white);
  }

  &-warning {
    .var-alert(@alert-warning-bg-color, @alert-warning-bg-color, @white);
  }

  &-danger {
    .var-alert(@alert-danger-bg-color, @alert-danger-bg-color, @white);
  }
}

複製程式碼

構建過程中,less 檔案無需轉換為css檔案,只需通過指令碼遍歷資料夾同步到對應目錄下即可,build-less.js程式碼:

const readFiles = async (filePath, name, callback) => {
  const files = fs.readdirSync(filePath)
  files.forEach(file => {
    const filedir = path.join(filePath, file)
    fs.stat(filedir, (error, stats) => {
      if (error) {
        return console.error('stats error:', error)
      }
      if (stats.isFile() && filedir.indexOf(name) > -1) {
        callback && callback(filedir)
      } else if (stats.isDirectory()) {
        readFiles(filedir, name, callback)
      }
    })
  })
}


const componentsPath = 'src/components'
readFiles(
  path.join(__dirname, '../', componentsPath),
  '.less',
  (file, error) => {
    if (error) {
      return console.error('read files error:', error)
    }
    fs.outputFileSync(
      file.replace(componentsPath, 'lib'),
      fs.readFileSync(file)
    )
  }
)
複製程式碼

文件介面:

如何開發React UI元件庫

貼一段Alert元件簡易程式碼

import React, { Component } from 'react'
import classNames from 'classnames'
import { getPrefix } from '../util/method'
import './index.less'

interface AlertProps {
  type?: 'success' | 'error' | 'warn' | 'info'
  message: React.ReactNode
  className?: string
}

export default class Alert extends Component<AlertProps> {
  render() {
    const { type = 'info' } = this.props
    const prefix = getPrefix('alert')
    const className = classNames(prefix, `${prefix}-${type}`)
    return <div className={className}>{this.props.message}</div>
  }
}

複製程式碼

在本地開發及測試完元件後需要釋出到倉庫測試,不建議釋出到npm官方倉庫中,因為畢竟是半成品,可以使用verdaccio在本地搭建一個私有倉庫進行測試

搭建私有參考可以參考使用verdaccio搭建私有npm倉庫

相關文章