摘要:手牽手搭建前端組件庫(kù)本文梳理如何搭建和構(gòu)建前端組件庫(kù)了解幾個(gè)問(wèn)題為何需要組件化大部分項(xiàng)目起源都是源于業(yè)務(wù)方的各種各樣的奇葩需求。作者是否私有,需要修改為才能發(fā)布到開(kāi)源協(xié)議參考配置添加文件發(fā)布時(shí),只有編譯后的目錄才需要被發(fā)布。
手牽手搭建前端組件庫(kù)
本文梳理如何搭建和構(gòu)建前端組件庫(kù).
了解幾個(gè)問(wèn)題
為何需要組件化?
大部分項(xiàng)目起源都是源于業(yè)務(wù)方的各種各樣的奇葩需求。隨著公司的業(yè)務(wù)發(fā)展,公司內(nèi)部開(kāi)始衍生出很多的B2C系統(tǒng)、后臺(tái)系統(tǒng),前端部門(mén)也疲于應(yīng)對(duì)越來(lái)越多同質(zhì)化的項(xiàng)目,這些項(xiàng)目在很多基礎(chǔ)模塊層、源代碼存在不小的相似,甚至存在相似的業(yè)務(wù)模塊。
筆者曾經(jīng)所在的一個(gè)電商團(tuán)隊(duì),前端成員基本每個(gè)人多做過(guò)登錄注冊(cè)、購(gòu)物車(chē)、支付、微信登錄...... 大量重復(fù)的業(yè)務(wù)代碼。由于組內(nèi)技術(shù)沒(méi)有強(qiáng)制規(guī)范
本質(zhì)上相同的東西,重復(fù)的去code就顯得浪費(fèi).
分析這些問(wèn)題發(fā)現(xiàn):
日漸增多的業(yè)務(wù)場(chǎng)景需求
前端資源有限,無(wú)法支持所有項(xiàng)目的快速迭代
公司內(nèi)部諸多產(chǎn)品業(yè)務(wù)混亂、體驗(yàn)不統(tǒng)一
于是開(kāi)發(fā)底層的工具去服務(wù)不同業(yè)務(wù)就很有必要:
設(shè)計(jì)一套公司內(nèi)部的基礎(chǔ)組件庫(kù)支撐各個(gè)前端項(xiàng)目,提升項(xiàng)目和業(yè)務(wù)的可用性和一致性。
一個(gè)前端團(tuán)隊(duì)擁有大量的業(yè)務(wù)場(chǎng)景和業(yè)務(wù)代碼,相似的頁(yè)面和代碼層出不窮,如何管理和抽象這些相似的代碼和模塊,絕大多數(shù)團(tuán)隊(duì)會(huì)遇到這樣的問(wèn)題。 不斷的拷代碼? 修改代碼?還是抽象成組件?顯然后者更高效。所以在多項(xiàng)目存在高度的可控、底層依賴(lài)的情況下,前端實(shí)現(xiàn)組件庫(kù)是最好的選擇。
組件化,又或者組件抽離的目的是為了功能共享方便維護(hù),其能夠帶來(lái)的好處是少寫(xiě)代碼,統(tǒng)一管理、統(tǒng)一維護(hù)。一套基礎(chǔ)組件代碼千錘百煉精而又精,從而起到快速支撐業(yè)務(wù)迭代,提升開(kāi)發(fā)效率的目的。
業(yè)務(wù)型組件庫(kù)
前端組件庫(kù)百花齊放,antd、element ui這些基礎(chǔ)組件庫(kù)已經(jīng)很強(qiáng)大,使用于各種業(yè)務(wù)場(chǎng)景。但是這些基礎(chǔ)組件的粒度是基于單個(gè)交互,而在交互與產(chǎn)品之間隔著各種各樣的模塊和業(yè)務(wù)場(chǎng)景,產(chǎn)品的匯聚源于各種基礎(chǔ)組件在業(yè)務(wù)邏輯的沾粘下集成為一個(gè)個(gè)項(xiàng)目,一個(gè)團(tuán)隊(duì)或多或少會(huì)有項(xiàng)目或模塊存在功能、交互流程的重復(fù)、本質(zhì)上的同質(zhì)化。
所以antd、element ui 這類(lèi)組件庫(kù)是基于單個(gè)非連續(xù)性的交互組件,一個(gè)組件代表著一次人機(jī)無(wú)副作用的操作與響應(yīng),其不思考實(shí)體、用戶(hù)、終端的狀態(tài),最小化的暴露和響應(yīng)組件內(nèi)部狀態(tài)。對(duì)于連續(xù)性的交互通常來(lái)說(shuō)與特點(diǎn)的業(yè)務(wù)場(chǎng)景有關(guān),存在諸多的外部依賴(lài),目前都是在各個(gè)業(yè)務(wù)模塊由用戶(hù)(coder)自行編寫(xiě)。
有沒(méi)有一種方法解決連續(xù)性交互流程的共用問(wèn)題?
解決的辦法是組件封裝包含業(yè)務(wù)場(chǎng)景的連續(xù)性交互流程,利用組件化將內(nèi)部依賴(lài)通過(guò)接口映射到外部。
前端架構(gòu)部門(mén)為業(yè)務(wù)部門(mén)提供業(yè)務(wù)型組件庫(kù)能夠有效提高開(kāi)發(fā)效率.
組件庫(kù)設(shè)計(jì)思路
組件是對(duì)一些具有相同業(yè)務(wù)場(chǎng)景和交互模式、交互流程代碼的抽象,組件庫(kù)首先應(yīng)該保證各個(gè)組件的視覺(jué)風(fēng)格和交互規(guī)范保持一致。組件庫(kù)的 props 定義需要具備足夠的可擴(kuò)展性,對(duì)外提供組件內(nèi)部的控制權(quán),使組件內(nèi)部完全受控。支持通過(guò) children 自定義內(nèi)部結(jié)構(gòu),預(yù)定義組件交互狀態(tài)。保持組件具有統(tǒng)一的輸入和輸出,完整的API.
組件庫(kù)的開(kāi)發(fā)我們需要考慮:
組件設(shè)計(jì)思路、需要解決的場(chǎng)景
組件代碼規(guī)范
組件測(cè)試
組件維護(hù),包括迭代、issue、文檔、發(fā)布機(jī)制
一個(gè)完整強(qiáng)大的組件庫(kù)需要多方面努力,回歸正題.
使用到的基礎(chǔ)技術(shù)
vue cil 3
npm
webpack
rollup(v1.2.2)
Demo
下面就手把手搭建一個(gè)前端偏業(yè)務(wù)性的組件庫(kù)。
組件庫(kù)包括:
message 組件: 一個(gè)封裝用于呈現(xiàn)后臺(tái)通過(guò) websocket 推送到前臺(tái)頁(yè)面的實(shí)時(shí)消息模塊;
pay 組件: 一個(gè)封裝用于實(shí)現(xiàn)商品支付的模塊
share 組件: 一個(gè)封裝用于實(shí)現(xiàn)商品、文章、視頻在各社交平臺(tái)分享的模塊
只拋出一個(gè)栗子,組件內(nèi)部實(shí)現(xiàn)略~
這里注意組件抽取的粒度,組件的抽離以一個(gè)完整的連續(xù)性交互為目地。
組件依賴(lài)數(shù)據(jù)、交互事件、控制權(quán)的暴露需要考慮全面,不同的上層業(yè)務(wù)部門(mén)都有自己對(duì)組件可配置的不同渴望。需要權(quán)衡,不能把配置化給搗鼓的永無(wú)止境到很難堪的局面。筆者曾經(jīng)就參與一個(gè)項(xiàng)目的組件化,組件抽離的面目全非,各種依賴(lài)、環(huán)境、狀態(tài)的配置,導(dǎo)致最后只有組件編寫(xiě)人員在看文檔加回憶的情況下才能搞清楚其來(lái)龍去脈.
從簡(jiǎn)單的開(kāi)始~
1、初始化組件庫(kù)目錄創(chuàng)建一個(gè)空項(xiàng)目
// 新建一個(gè)項(xiàng)目 vue create qw-ui
經(jīng)過(guò)vue cil3初始化后的qw-ui目錄:
├─docs │ ├─public │ ├─src │ .gitignore │ babel.config.js │ package-lock.json │ package.json │ README.md │ vue.config.js │
此時(shí)為了方便組件庫(kù)的代碼管理,將目錄結(jié)構(gòu)修改為:
├─src // 用作示例 Demo │ ├─packages // 新增 packages 用于編寫(xiě)存放組件 │ ├─lib // 新增 lib 用于存放編譯后的輸出文件 │ .gitignore │ babel.config.js │ package-lock.json │ package.json │ README.md │ vue.config.js │
目錄結(jié)構(gòu)可以更具需要調(diào)整.
2、修改 vue.config.js 配置vue cli3 提供一個(gè)可選的 vue.config.js 配置文件。這個(gè)文件存在則他會(huì)被自動(dòng)加載,所有的對(duì)項(xiàng)目和webpack的配置,都在這個(gè)文件中。
修改 vue.config.js 配置的目的主要是:
使 Demo 可訪問(wèn),實(shí)現(xiàn)對(duì) src目錄的編譯處理;
提供對(duì) package的編譯、構(gòu)建處理
做以下兩處修改:
修改項(xiàng)目的入口
entry 字段為項(xiàng)目入口
入口修改使用 Vue CLI 3 的 page屬性來(lái)配置:
module.exports = { pages: { index: { // page 的入口 entry: "src/main.js", // 模板來(lái)源 template: "public/index.html", // 在 dist/index.html 的輸出 filename: "index.html" } } }
添加對(duì) packages 目錄的編譯處理
packages 是我們后來(lái)新增的一個(gè)目錄,默認(rèn)是不被 webpack 處理的,所以需要通過(guò)添加配置對(duì)該目錄的編譯支持。
新增編譯處理目錄,需要通過(guò)webpack的鏈?zhǔn)讲僮鱟hainWebpack函數(shù)實(shí)現(xiàn):
module.exports = { pages: { index: { // page 的入口 entry: "examples/main.js", // 模板來(lái)源 template: "public/index.html", // 在 dist/index.html 的輸出 filename: "index.html" } }, chainWebpack: config => { // packages和examples目錄需要加入編譯 config.module .rule("js") .include.add(/packages/) .end() .include.add(/src/) .end() .use("babel") .loader("babel-loader") .tap(options => { // 修改它的選項(xiàng)... return options; }); } }
執(zhí)行 npm run vue-cli-service serve , 實(shí)現(xiàn)對(duì)Demo的訪問(wèn).
3、編寫(xiě) packages 組件庫(kù)創(chuàng)建一個(gè) message組件
創(chuàng)建組件
在 packages 目錄下,所有的單個(gè)組件都以文件夾的形式存儲(chǔ),這里創(chuàng)建一個(gè)目錄 message 文件夾;
在 message/ 目錄下創(chuàng)建 src/ 目錄存儲(chǔ)組件源碼,所有 message 依賴(lài)的除第三方資源都存放與該目錄下;
在 /message目錄下創(chuàng)建 index.js` 文件對(duì)外提供對(duì)組件的引用
示例代碼:
message/index.js 對(duì)外提供應(yīng)用
// message/index.js import message from "./src/message " message .install = function (Vue) { Vue.component(message .name, message ) } export default message
// message/src/message .js
需要注意的是,組件 mesage 必須聲明 name 屬性,這個(gè) name 就是組件的標(biāo)簽,如:
packages/message目錄結(jié)構(gòu)如下:
packages/message ├─index.js │ ├─src │ message.vue │ st.png // 組件依賴(lài)的圖片 │ index.scss // 組件依賴(lài)的樣式文件
導(dǎo)出 packages 組件庫(kù)
修改 /packages/index.js 文件,整合所有組件,并對(duì)整個(gè)組件庫(kù)進(jìn)行導(dǎo)出:
// 導(dǎo)入組件 import hello from "./hello" // 存儲(chǔ)組件列表 const components = [ hello ] // 定義 install 方法,接收 Vue 作為參數(shù)。如果使用 use 注冊(cè)插件,則所有的組件都將被注冊(cè) const install = function (Vue) { // 判斷是否安裝 if (install.installed) return // 遍歷注冊(cè)全局組件 components.map(component => Vue.component(component.name, component)) } // 判斷是否是直接引入文件 if (typeof window !== "undefined" && window.Vue) { install(window.Vue) } export default { // 導(dǎo)出的對(duì)象必須具有 install,才能被 Vue.use() 方法安裝 install, // 以下是具體的組件列表 hello }
到此,構(gòu)建組件庫(kù)的環(huán)境準(zhǔn)好好了
?
### 4、發(fā)布組件庫(kù)到 npm
packages 目錄的編譯打包
在 package.json的 scripts 字段中新增一下命令:
"lib": "vue-cli-service build --target lib --name kui --dest lib packages/index.js"
vue cil3 提供了 [庫(kù)模式](https://cli.vuejs.org/zh/guide/build-targets.html#%E5%BA%93) 來(lái)打包第三方庫(kù)的開(kāi)發(fā),packages 的編譯打包需要使用庫(kù)模式
--target: 構(gòu)建目標(biāo),默認(rèn)為應(yīng)用模式。這里修改為 lib 啟用庫(kù)模式。
--dest : 輸出目錄,默認(rèn) dist。這里我們改成 lib
[entry]: 最后一個(gè)參數(shù)為入口文件,默認(rèn)為 src/App.vue。這里我們指定編譯 packages/ 組件庫(kù)目錄。
在 vue cil3 庫(kù)模式中,Vue 是外置的。這意味著包中不會(huì)有 Vue,即便你在代碼中導(dǎo)入了 Vue。如果這個(gè)庫(kù)會(huì)通過(guò)一個(gè)打包器使用,它將嘗試通過(guò)打包器以依賴(lài)的方式加載 Vue;否則就會(huì)回退到一個(gè)全局的 Vue 變量。
配置好了后,執(zhí)行編譯命令:
npm run lib
稍后控制臺(tái)輸出,即編譯完成:
DONE Compiled successfully in 5988ms16:05:35 File Size Gzipped libkui.umd.min.js 8.08 KiB 4.55 KiB libkui.umd.js 17.78 KiB 7.31 KiB libkui.common.js 17.41 KiB 7.19 KiB libkui.css 0.10 KiB 0.10 KiB Images and other types of assets omitted.
Total task duration: 8.71s ```
package.json 配置
name: 包名,該名字是唯一的。可在 npm 官網(wǎng)搜索名字。
version: 版本號(hào),每次發(fā)布至 npm 需要修改版本號(hào),不能和歷史版本號(hào)相同。
description: 描述。
main: 入口文件,該字段需指向我們最終編譯后的包文件。
keyword:關(guān)鍵字,以空格分離希望用戶(hù)最終搜索的詞。
author:作者
private:是否私有,需要修改為 false 才能發(fā)布到 npm
license: 開(kāi)源協(xié)議
參考配置:
{ "name": "qw-ui", "version": "0.1.0", "private": false, "main": "lib/kui.umd.min.js", "description": "qw-ui", "keyword": "qw-ui", "author":"luojh", "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", "lib": "vue-cli-service build --target lib --name kui --dest lib packages/index.js" } }
添加 .npmignore 文件
發(fā)布時(shí),只有編譯后的 lib 目錄、package.json、README.md才需要被發(fā)布。所以通過(guò)配置.npmignore文件忽略不需要提交的目錄和文件。
# 忽略目錄 examples/ packages/ public/ # 忽略指定文件 vue.config.js babel.config.js *.map # 本地文件 .env.local .env.*.local # 日志文件 npm-debug.log* yarn-debug.log* yarn-error.log* # 編輯器緩存文件 .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw*
發(fā)布到 npm
首先需要在 npm 官網(wǎng)上注冊(cè)一個(gè)賬號(hào),通過(guò) npm adduser 命令創(chuàng)建一個(gè)賬戶(hù),或者在 npm 官網(wǎng)注冊(cè)
注冊(cè)完成后在本地命令行中登錄:
npm login
執(zhí)行發(fā)布命令,發(fā)布到 npm
npm publish
npm 淘寶鏡像不支持 publish 命令,如果設(shè)置了淘寶鏡像,publish 前需將鏡像設(shè)置會(huì) npm :
npm config set registry http://registry.npmjs.org
npm publish時(shí),本地cmd終端需通過(guò)管理員運(yùn)行
?
### 5.使用組件庫(kù)
安裝發(fā)布的組件庫(kù):
npm i qw-ui
使用組件:
# 在 main.js 引入并注冊(cè) import qwui from "qw-ui" Vue.use(qwui) # 在組件中使用
完!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/53730.html
摘要:手牽手搭建前端組件庫(kù)本文梳理如何搭建和構(gòu)建前端組件庫(kù)了解幾個(gè)問(wèn)題為何需要組件化大部分項(xiàng)目起源都是源于業(yè)務(wù)方的各種各樣的奇葩需求。作者是否私有,需要修改為才能發(fā)布到開(kāi)源協(xié)議參考配置添加文件發(fā)布時(shí),只有編譯后的目錄才需要被發(fā)布。 手牽手搭建前端組件庫(kù) 本文梳理如何搭建和構(gòu)建前端組件庫(kù). showImg(https://segmentfault.com/img/bVboZDt?w=1200&...
摘要:在文末,我會(huì)附上一個(gè)可加載的模型方便學(xué)習(xí)中文藝術(shù)字渲染用原生可以很容易地繪制文字,但是原生提供的文字效果美化功能十分有限。 showImg(https://segmentfault.com/img/bVWYnb?w=900&h=385); WebGL 可以說(shuō)是 HTML5 技術(shù)生態(tài)鏈中最為令人振奮的標(biāo)準(zhǔn)之一,它把 Web 帶入了 3D 的時(shí)代。 初識(shí) WebGL 先通過(guò)幾個(gè)使用 Web...
摘要:也是一款優(yōu)秀的響應(yīng)式框架站點(diǎn)所使用的一套框架為微信服務(wù)量身設(shè)計(jì)的一套框架一組很小的,響應(yīng)式的組件,你可以在網(wǎng)頁(yè)的項(xiàng)目上到處使用一個(gè)可定制的文件,使瀏覽器呈現(xiàn)的所有元素,更一致和符合現(xiàn)代標(biāo)準(zhǔn)。 GitHub 值得收藏的前端項(xiàng)目 整理與收集的一些比較優(yōu)秀github項(xiàng)目,方便自己閱讀,順便分享出來(lái),大家一起學(xué)習(xí),本篇文章會(huì)持續(xù)更新,版權(quán)歸原作者所有。歡迎github star與fork 預(yù)...
閱讀 2060·2021-11-23 09:51
閱讀 3353·2021-09-28 09:36
閱讀 1120·2021-09-08 09:35
閱讀 1758·2021-07-23 10:23
閱讀 3258·2019-08-30 15:54
閱讀 2998·2019-08-29 17:05
閱讀 438·2019-08-29 13:23
閱讀 1294·2019-08-28 17:51