当前位置: 首页 > Web前端 > HTML

【手拉手】搭建前端组件库(一)

时间:2023-04-02 19:54:50 HTML

手拉手搭建前端组件库大多数项目的起源都源于??业务方的各种奇葩需求。随着公司业务的发展,公司内部衍生出很多B2C系统和后台系统,前端部门也为应对越来越多的同质化项目而吃力。这些项目在很多基础模块层和源代码上都有相当大的差距。类似,甚至类似的业务模块都存在。在笔者曾经工作过的一个电商团队中,每个前端成员基本上都在做登录注册、购物车、支付、微信登录……一大堆重复的业务代码。由于组内的技术对本质上相同的东西没有强制规范,重复代码去除是浪费。分析这些问题发现:越来越多的业务场景需要有限的前端资源,无法支持所有项目的快速迭代。体验不统一,需要开发底层工具服务于不同的业务:设计一套内部基础组件库来支持各种前端项目,提高项目和业务的易用性和一致性。一个前端团队有大量的业务场景和业务代码,相似的页面和代码层出不穷,如何对这些相似的代码和模块进行管理和抽象,大多数团队都会遇到这样的问题。不断复制代码?修改代码?还是抽象成组件?显然后者效率更高。因此,在多个项目中高度可控、低级依赖的情况下,组件库的前端实现是最好的选择。组件化,或者说组件分离的目的是功能共享,方便维护。它能带来的好处是少写代码,统一管理,统一维护。细化和细化了一套基础组件代码,快速支撑业务迭代,提升开发效率。前端组件库百花齐放,antd、elementui等基础组件库已经非常强大,应用于各种业务场景。但是,这些基础组件的粒度是以单一交互为基础的,交互与产品之间存在各种模块和业务场景。产品的聚合来源于各种基础组件在业务逻辑的粘性下集成到项目中,一个团队或多或少都会有项目或模块,这些项目或模块具有功能性、交互过程的重复性、本质上的同质性。因此antd、elementui等组件库都是基于单个不连续的交互组件。一个组件代表一个人机操作和响应,没有副作用。不考虑实体、用户、终端的状态,尽量减少暴露和响应。组件内部状态。持续交互通常与具体业务场景相关,外部依赖较多,目前由用户(码农)编写在各个业务模块中。有没有办法解决持续交互流的共享问题?解决方案是将包括业务场景在内的持续交互过程封装在组件中,通过组件化的方式将内部依赖通过接口映射到外部。前端架构部为业务部门提供面向业务的组件库,可以有效提高开发效率。组件库设计思路组件是对一些具有相同业务场景、交互方式、交互流程的代码的抽象。组件库首先要保证视觉风格和交互规范保持一致。组件库的props定义需要有足够的可扩展性,以向外部提供组件的内部控制,从而使组件的内部得到充分的控制。支持通过children自定义内部结构,预定义组件的交互状态。保持组件统一的输入输出,以及完整的API。组件库的开发需要考虑:组件设计思路、需要解决的场景、组件代码规范、组件测试、组件维护,包括迭代、issue、文档、发布机制。一个完整而强大的组件库需要付出很多努力,言归正传。使用的基础技术是vuecil3npmwebpackrollup(v1.2.2)Demo。接下来,我们将构建一个面向前端业务的组件库。组件库包括:消息组件:用于呈现通过websocket从后台推送到前台页面的实时消息模块的封装;支付组件:用于实现商品支付的包;各个社交平台共享的模块只举个栗子,省略了组件内部实现。这里要注意组件抽取的粒度,组件的抽取是针对一个完整的连续交互。需要综合考虑组件对数据的依赖、交互事件、控制权的暴露等。不同的上层业务部门对组件配置的需求不同。需要有所取舍,配置不能没完??没了到尴尬的境地。笔者曾经参与过一个项目的组件化。组件分离得面目全非,各种依赖、环境、状态的配置导致只有组件编写者在阅读文档和回忆后才能弄清楚项目的来龙去脉。从简单的~1开始。初始化组件库目录并创建一个空项目//新建一个项目vuecreateqw-uivuecil3初始化后的qw-ui目录:├─docs│├─public│├─src│.gitignore│babel.config。js│package-lock.json│package.json│README.md│vue.config.js│此时为了方便组件库的代码管理,目录结构改为:├─src//用作demodemo│├─packages//新的包用于编写存储组件│├─lib//新的libs用于存储编译后的输出文件│.gitignore│babel.config.js│package-lock.json│package.json│README.md│vue.config.js│目录结构可以根据需要调整。2.修改vue.config.js配置vuecli3提供一个可选的vue.config.js配置文件。如果这个文件存在,它会被自动加载。项目和webpack的所有配置都在这个文件中。修改vue.config.js的配置主要是为了让Demo可以访问,实现src目录的编译处理;对包的编译构建处理提供如下两个修改:修改项目入口字段为项目入口入口修改使用VueCLI3的page属性配置:module.exports={pages:{index:{//页面入口entry:'src/main.js',//templatesourcetemplate:'public/index.html',//在dist/index.html的输出文件名中:'index.html'}}}添加packages目录的编译处理。packages是我们后面新增的一个目录,默认不被webpack处理,所以需要通过为该目录添加Compile支持来进行配置。添加新的编译处理目录,需要通过webpack的链式Webpack功能实现:module.exports={pages:{index:{//页面入口entry:'examples/main.js',//模板源模板:'public/index.html',//dist/index.html中的输出文件名:'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=>{//修改它的选项...returnoptions;});}}执行npmrunvue-cli-serviceserve实现对Demo的访问。3.编写packages组件库创建一个message组件,在packages目录下创建一个组件,所有的单个组件都以文件夹的形式存放,这里创建一个目录message文件夹;在message/目录下创建一个src/目录,用于存放组件的源代码,除第三方资源外的所有message依赖都存放在该目录下;在/message目录下创建一个index.js`文件,提供组件的外部引用示例代码:message/index.js提供外部应用//message/index.jsimportmessagefrom'./src/message'message。install=function(Vue){Vue.component(message.name,message)}导出默认消息//message/src/message.js需要注意的是,组件message必须声明name属性,这个name就是组件的标签,如:packages/message目录结构如下:packages/message├─index.js│├─src│message.vue│st.png//组件依赖pictures│index.scss//组件依赖样式文件导出packages组件库修改/packages/index.js文件,整合所有组件,更新整个组件库export://导入组件importhellofrom'./hello'//存储组件列表constcomponents=[hello]//定义install方法,接收Vue作为参数如果使用use注册插件,所有组件会被注册constinstall=function(Vue){//判断是否安装if(install.installed)return//遍历并注册全局组件components.map(component=>Vue.component(component.name,component))}//判断是否直接导入文件if(typeofwindow!=='undefined'&&window.Vue){install(window.Vue)}exportdefault{//导出的对象必须有install才能被Vue.use安装()methodinstall,//下面是具体的组件列表hello}至此,构建组件库的环境就准备好了###4.将组件库发布到npmpackages目录下进行编译打包。在package.json的scripts字段添加如下命令:"lib":"vue-cli-servicebuild--targetlib--namekui--destlibpackages/index.js"vuecil3provides[librarymode](https://cli.vuejs.org/zh/guide/build-targets.html#%E5%BA%93)打包第三方库的开发,packages的编译打包需要使用library模式——-target:构建目标,默认为应用模式。此修改为lib启用库模式。--dest:输出目录,默认dist。这里我们改成lib[entry]:最后一个参数是入口文件,默认是src/App.vue。这里我们指定编译packages/组件库目录。在vuecil3库模式下,vue是external的。这意味着包中不会有Vue,即使您在代码中导入Vue。如果库将通过捆绑器使用,它将尝试通过捆绑器将Vue作为依赖项加载;否则它将退回到全局Vue变量。配置完成后,执行编译命令:npmrunlib稍后控制台输出,即编译完成:DONECompiledsuccessfullyin5988ms16:05:35FileSizeGzippedlib\kui.umd.min.js8.08KiB4.55KiBlib\kui.umd.js17.78KiB7.31KiBlib\kui.common.js17.41KiB7.19KiBlib\kui.css0.10KiB0.10KiB图像和其他类型的资产被省略。Totaltaskduration:8.71s```package.json配置名称:包名,名称是唯一的。可以在npm官网搜索名字。version:版本号,每次发布到npm需要修改版本号,不能与历史版本号相同。描述:描述。main:入口文件,这个字段需要指向我们最终编译好的包文件。keyword:关键词,用空格分隔到你希望用户最终搜索的词。author:作者private:是否私有,需要改为false才能发布到npmlicense:开源协议参考配置:{"name":"qw-ui","version":"0.1.0","private":false,"main":"lib/kui.umd.min.js","description":"qw-ui","keyword":"qw-ui","author":"luojh","脚本”:{“服务”:“vue-cli-serviceserve”,“build”:“vue-cli-servicebuild”,“lint”:“vue-cli-servicelint”,“lib”:“vue-cli-servicebuild--targetlib--namekui--destlibpackages/index.js"}}添加.npmignore发布时只需要发布编译好的lib目录、package.json、README.md。所以通过配置.npmignore文件忽略不需要提交的目录和文件。#忽略目录examples/packages/public/#忽略指定文件vue.config.jsbabel.config.js*.map#本地文件.env.local.env.*.local#日志文件npm-debug.log*yarn-debug.log*yarn-error.log*#Editorcachefile.idea.vscode*.suo*.ntvs**.njsproj*.sln*.sw*发布到npm,首先需要在npm上注册一个账号npm官网,通过npmadduser命令创建账号,或者在npm官网注册后在本地命令行登录:npmlogin执行发布命令发布到npmnpmpublishnpm淘宝镜像不支持发布命令。如果设置淘宝镜像,发布前必须先设置镜像遇到npm时:npmconfigsetregistryhttp://registry.npmjs.orgnpmpublish,本地cmd终端需要管理员运行###5.使用组件库安装发布的组件库:npmiqw-ui使用组件:#在main.js中引入并注册importqwuifrom'qw-ui'Vue.use(qwui)#Use完成!