首頁 >web前端 >js教程 >使用React如何進行元件庫的開發

使用React如何進行元件庫的開發

亚连
亚连原創
2018-06-07 15:07:142301瀏覽

本篇文章主要介紹了詳解使用React進行元件庫開發,現在分享給大家,也為大家做個參考。

最近針對日常業務需求使用react封裝了一套[元件庫], 大概記錄下整個開發過程中的心得。由於篇幅原因,在這裡只對開發過程中比較糾結的選型和打包等進行討論,後續再對具體組件的封裝進行討論。

概述

我們都知道,元件化的開發模式對於我們的開發效率有著極大的提升,針對我們日常使用的基本元件進行封裝,可以大量的簡化我們對於基本UI的關注度,讓我們的工作聚焦在業務邏輯上,很好的分離業務與基礎UI的程式碼,使得整個專案更有調理,這也是我們要進行本元件庫開發的原因。

然而現有React開源元件有很多,像是ant-design和material-ui等等,是否需要花費精力打造適合自身團隊的元件庫往往需要酌情考慮。我們來看下我現有團隊及業務的幾個特點:

  1. 前端人員較多,需要相互協作,且有餘力對元件進行開發

  2. #產品業務相對複雜,需對某些元件進行客製化開發

  3. 已經有成熟的設計規範,針對各種基礎元件、基礎樣式等進行定義

  4. 目前的項目較為凌亂,第三方元件引用雜亂無章

可以看出,我們擁有封裝自己元件的精力和基礎,並且擁有透過基礎組件封裝改變目前開發現狀的需求。所以,這件事情是我們應該並且需要盡快完成的事情。

技術選型

針對元件庫的封裝,我們首先面對的是技術選型以及方案的規劃。大概包括以下兩點:

  1. 最基本的技術方案

  2. #開發流程與規格

技術方案選擇

Webpack React Sass

由於團隊現有的專案都是基於React Redux進行開發的,那麼我們選擇的開發語言無疑是React。

SASS

針對css選擇,雖然現在針對元件化開發,比較流行CSS Modules和CSS-IN-JS兩中模組化解決方案,我們更希望我們的組件是可進行客製化的。因此針對元件,我們以Sass作為預編譯語言,提搞效率和規範性。配合css-modules,我們可以很方便的進行針對實際需求進行樣式變更。例如我們有一個Tab元件,我們已經定義了其通用的樣式:

.tip-tab {
 border: 1px solid #ccc;
}
.tip-tab-item {
 border: 1px solid #ccc;
 
 &.active {
  border-color: red;
 }
}

而在業務中,針對某一個需求,我們需要針對Tab元件的樣式進行微調。讓其在啟動(active)狀態下border-color是藍色的。你當然可以說,我們可以讓我們的元件暴露出一些props,針對這些修改進行配置,傳入不同的props對應不同的風格。但是我們往往無法滿足所有的業務需求,不可能針對元件把各種樣式都封裝進去。針對這種方案,我們採用css-modules為其添加唯一的模組樣式:

<Tab styleName="unique-tab" />

針對該模組,對其進行基本樣式的修改:

.unique-tab {
 :global {
   .tip-tab-item {
    border-color: #eee;
    
    &.active {
     border-color: blue;
    }
   }
 }
}

這樣,針對該模組的客製化樣式,能很好的進行針對需求的樣式定制,同時不對全局樣式進行污染。

Icon

針對專案圖標,計畫使用svg-sprite方案。但是由於產品處於不斷迭代的過程中,新的圖標不斷在增加。目前我們不會對圖示統一進行打包,而是在每次進行元件打包的過程中,從專案中匯入所有的圖示。用以下方式進行引入:

import Icon from &#39;@common/lib&#39;
import errorIcon from &#39;@images/error.svg&#39;

<Icon link={errorIcon} />

其實更好的方式是針對所有的圖標進行統一打包,生成svg-spirte文件(具體原理可以查詢svg-sprite,在此不再贅述)。當我們進行使用時,只需直接引用即可,避免每次都進行打包,減少webpack處理依賴的時間:

<Icon type="error" />

開發流程和規格

針對開發流程和規範,我們遵循以下幾個原則:

  1. 元件庫完全獨立於專案進行開發,以便於後續多個專案進行使用等

  2. #元件庫包含三種模式:開發,測試,打包,文件案例,區分不同的入口及狀態

  3. 使用pure-renderautobind等盡可能保證元件的效能及效率

  4. 保證props和回呼的語意性,如回呼統一使用handleXXX進行處理

為了便於後續的擴展,我們更希望整個元件庫完全脫離於專案進行開發。確保元件庫僅對於最基本的元件進行封裝,將專案UI程式碼與業務邏輯進行分離。

针对不同的模式下,我们有不同的文件入口,针对开发模式,我们启动一个dev-server, 在里面对组件进行基本的封装,并进行调试。打包时,我们只需对组件内容进行封装,暴露统一的接口。在文档中,我们需要进行案例和说明的展示。所以我们在利用webpack的特性进行各种环境的配置:

npm run dev // 开发
npm run test // 测试
npm run build // 构建
npm run styleguide // 文档开发
npm run styleguide:build // 文档打包

组件库作为项目的最小力度支持,我们需要保证其最基本的渲染效率,因此我们采用pure-render/autobind等对其进行基本的优化。React有很多优化方式,在此不进行赘述。

打包

基础

针对组件库的打包,我们以UMD格式对其进行打包。webpack可以针对输出进行格式设置:(引自cnode)

  1. “var” 以变量方式输出

  2. “this” 以 this 的一个属性输出: this[“Library”] = xxx;

  3. “commonjs” 以 exports 的一个属性输出:exports[“Library”] = xxx;

  4. “commonjs2” 以 module.exports 形式输出:module.exports = xxx;

  5. “amd” 以 AMD 格式输出;

  6. “umd” 同时以 AMD、CommonJS2 和全局属性形式输出。

配置如下:

output: {
 path: config.build.assetsRoot,
 filename: utils.assetsPath(&#39;js/[name].js&#39;),
 chunkFilename: utils.assetsPath(&#39;js/[id].js&#39;),
 library: &#39;TipUi&#39;,
 libraryTarget: &#39;umd&#39;
}

依赖

很明显,我们封装的是一个针对React的组件库,并不应该把React引用进去。一般我们可以采用externals的方式对其进行处理。

在这里, 我们采用dll方式将其与其他第三方依赖统一进行打包,并将manifest.json和三方依赖的输出文件输出到项目中去,在项目中也使用dllReference进行引用。避免在项目中使用到这些依赖时重复进行打包。

同时,由于我们的组件库处于一个不断维护的状态。这就需要我们维持好项目库和项目之间的打包关系,具体的流程如图所示:

在每次进行项目打包的时候,首先检测UI库是否有更新,若没有更新,则直接进行打包。反之继续检测dll的依赖是否有变化,若有,则打包dll,否则直接打包组件库内容。然后将输出结果同步到项目中,再进行最终打包。

当然,以上的这些流程都是自动进行的。

文档和示例

一个完善的文档对于一个组件库是及其重要的,每个组件有什么样的配置参数,拥有哪些事件回调,对应的Demo和展示效果。假设没有这些,除了封装组件的人,没有人知道它该如何使用。但是写文档的过程往往是痛苦的,在这里推荐几个文档生成库,可以极大的简化文档工作:

docsify 基于Vue的组件生成器,轻量好用
react-styleguidist 基于React的组件库文档生成器,自动根据注释生成文档,支持Demo展示。超好用
bisheng ant design自己写的文档生成器

我们使用的styleguidist, 可以将md自动转化为文档,支持在md内直接调用你封装好的组件并进行展示,简单好用。最后封装的文档大概长这样:

总结

其实封装组件库这种工作有很多的东西值得琢磨和钻研,由于篇幅原因,在这里只对开发过程中比较纠结的选型和打包等进行讨论,后续再对具体组件的封装进行讨论。在书写的同时,不断参考下ant design这种优秀的组件库,能学到很多的东西。更深刻的理解封装组件的思想,是一个很好的过程。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用Vue实现底层原理(详细教程)

在nodejs环境下微信扫码支付功能如何实现?

在JS中如何实现运动缓冲效果(详细教程)

以上是使用React如何進行元件庫的開發的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn