当前位置: 首页 > 后端技术 > Node.js

微店前端工程的迭代史

时间:2023-04-03 12:56:07 Node.js

文章同步于:https://github.com/hoperyy/bl...微店前端工程从一个内部产品开始vbuilder,我们有一个开源版本bio-cli。去年我们也写了一篇介绍这款产品的文章:bio:一站式前端开发工具。时隔这么久,我们在前端工程方面做了哪些改变,遇到了哪些问题,用了哪些方案来解决这些问题等等,值得再次和大家分享。v0.0在这里介绍一下背景,为什么要开发vbuilder。总体思路是整合重复性工作。当时团队面临几个问题:Duplication:每个项目都需要新建一个脚手架(webpack/gulp等)Miscellaneous:项目目录下同时包含脚手架文件和业务文件Miscellaneous:packge.json中的依赖都是scaffolded依赖,也有业务依赖,难以区分,难以更新:一旦确定了scaffolding,几乎就不再更新了,比如webpack1.0的项目很有可能一直停留在webpack1.0的状态。同一个项目成本高,比如:需要重新了解对应的项目配置等。总结如下:基于以上问题,我们开始了vbuilder的研发。最终产品作为命令行发布。此时vbuilder处于V0.0状态。V1.0vbuilderV1.0提供了以下能力:默认命令集:内置一套常用功能开发的命令集,包括mock/update/help等静默更新:用户安装后无需关注更新一个命令一次,更新自行静默完整的聚合脚手架:隐藏项目中的脚手架配置,统一管理,开发者可以快速专注于业务逻辑开放访问脚手架:没有类型限制技术栈(vue/react/angular/weex等),开放接入不同技术栈插件:除了内置命令集,插件扩展命令集,供团队成员实现自定义逻辑与vbuilder的不断推进,我们欣喜地看到团队发生了一些变化:便捷:一条命令创建新项目,直接开始业务开发纯粹的业务开发:项目目录下只保留业务文件,项目配置如脚手架是隐藏的。更新:脚手架收敛到统一管理,统一更新,尽可能应用最新的技术栈协同:大部分项目协同的成本范围收敛到“业务逻辑”,剔除“工程配置逻辑”,大大降低成本协作开放性:在脚手架配置融合的同时,开放接入各种技术栈脚手架,如weex/vms/后台管理/服务端项目协作:团队统一技术更新可以快速进行,不会再有持续不断的问题由于不同的项目配置而适应。总结如下:V1.0出现后,推广非常顺利。在推广过程中,坚持以下原则:提高效率:帮助业务开发者节省时间,分担负担:参与生态建设(脚手架开发维护、插件开发)的开发者至少会获得性能积分。Easytouse:简单易用,欲求有用V1.0Basic解决以下角色痛点:后端同学:100%覆盖内部系统开发场景前端同学:绝大部分业务场景覆盖脚手架开发者:强大的脚手架开发完成后,可以快速提升插件开发者:自定义命令,满足个性化开发问题V1.0Closed高度定制化的工程配置需求更难实现话说还是一个丢进桶里。此时需要打开一个新的脚手架,重新连接vbuilder系统。在“开放性”方面,则打了折扣。插件开发的冲突因为vbuilder是基于命令行开发的,所以插件开发者扩展自定义命令,仍然是自定义命令行。随着团队的不断扩大,不同的插件很容易使用同一个命令同时安装。状态,重复命令。V2.0V2.0至少要解决V1.0存在的问题,同时需要有更明确的发展方向。但是,V2.0仍然是基于命令行的。V2.0如何解决关闭问题?V1.0的思想是“封闭”。虽然有一定程度的开放,但还不够。V2.0增加了“开放”能力,脚手架配置可以隐藏,也可以随时暴露给项目配置,进行定制化开发。当然,你会遇到脚手架难以统一管理的问题,还是有办法解决的。因为暴露的项目配置是由vbuilder提供的,vbuilder可以很容易地统计出哪些项目使用了自定义脚手架,并将通用的工具包交付给项目。V2.0如何解决插件开发的冲突1:插件之间的冲突比如有两个插件,都有一个命令运行。如果用户安装了这两个插件,则执行run命令时会触发这两个插件的逻辑。在某些情况下,这不是用户希望看到的,也许TA想要的是运行插件A的命令运行。问题2:插件命令集与内置命令的冲突例如,内置-incommandset有命令init,某个plugin也有init。那么当用户执行init命令时,逻辑还是会执行两次。如何解决?我们结合使用了以下方案:vbuilder检测是否有重复的命令,如果有则提示用户是全部运行还是选择运行某个插件中的某个命令来圈定该命令的生效条件。vbuilder的命令行是基于commander的。我们扩展了一些基于指挥官的方法。如果我们想让插件中的命令show只有在项目目录下存在xx.show文件时才生效,那么代码如下:commander.command('show[param]').effect(cwd=>fs.existsSync(path.join(cwd,'xx.show')))----这是我们的扩展command.description('Mycustomcommand').action((param,options)=>{console.log('我的节目');});为内置命令集声明为“内置命令”,插件命令可以阻止内置命令的执行。生效,但是内置命令不生效,怎么办?我们扩展了commander的两个方法:declareDefault声明内置命令,preventDefault阻止内置命令执行。定义内置命令时,代码如下:action((param,options)=>{console.log('initinside');});开发插件命令时,代码如下:commander.command('init[param]').preventDefault()---防止内置命令执行.description('built-ininitCommand')。action((param,options)=>{console.log('initinside');});Commander的源码只有1000行左右,逻辑还是很清晰的,扩展也很方便,这里就不一一列举了。V2.0新功能在命令行场景下,我们将vbuilder定义为公司内部开发的“水电煤”基础设施。通过vbuilder,我们增加了以下场景:支持chrome插件es6/7开发,支持组件库快速开发,支持js工具库快速开发,支持文档库快速打开等。感谢插件,通过充分调动开发者的积极性,我们可以无限扩展其能力。v3.0我们还没有进入3.0的开发,但是有几个方向可以尝试:cloudIDE(内部有这样的平台)vscode定制IDE,这种场景比较适合非常大的团队,IDE定制开发应用场景更多,开发效率更快的云化(其实并不新鲜,很多公司已经实现了云化)。以上就是我们目前在微店前端工程领域的一些实践和思考。希望对大家有所帮助。帮助。