4

Velocity 不用愁!Velocity 系统的前端工程化之路 - 京东云技术团队

 1 year ago
source link: https://www.cnblogs.com/jingdongkeji/p/17427897.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Velocity 不用愁!Velocity 系统的前端工程化之路

Velocity是一个基于Java的Web页面模版引擎。十多年前,Velocity将Java代码从Web页面中分离出来,使得开发者能够并行网页开发和Java开发。随着十年前后端分离的浪潮涌动,回首再面对这些基于Velocity的旧系统,无论是后端还是前端人员维护,都会存在诸多问题:

(1)后端人员维护:不熟悉前端开发模式,需要花费大量精力学习UI和Js框架;

(2)前端人员维护:Velocity渲染依赖Java环境,需要花费大量精力学习Maven工程、环境配置,且前端MVC框架版本老,开发效率低。

这种情况广泛存在于零售内部的一些旧系统中,且业务需求的不断迭代,会导致系统维护成本越来越高。针对需要频繁迭代的页面模块,常见的应对措施是采用前后端分离方案,对页面进行整体重构,但如此以后,整体重构的代价是巨大的,主要体现在如下几点:

(1)需要覆盖所有的业务场景和需求;

(2)缺乏覆盖全场景的测试物料;

(3)页面重构本身不带来业务价值。

我们团队承担了B端业务,由于业务启动时间早,也不可避免需要维护这些Velocity系统。

针对老系统维护难的痛点,我们在实践中探索了一种对老系统侵入程度低、技术架构缓步升级的技术路线,分为4个步骤,分别是(1)搭建Velocity+MVC+MVVC混合架构;(2)建立Velocity单文件组件化能力;(3)创建Velocity本地沙盒环境;(4)Velocity页面前后端分离。下面分别进行详细说明:

一、 搭建Velocity + MVC + MVVC混合架构

Velocity系统多数还在使用JQuery等Js框架,开发效率低,亟待改善。对比MVC框架和MVVC框架,MVVC框架封装了视图层逻辑,开发效率显著提升。

因此第一个步骤是在Velocity页面中引入MVVC框架,实现两套技术架构的共存。我们引入了Vue以及配套的UI组件库,考虑Vue的主要因素有以下几点:

(1)Vue支持Js资源链接的方式引入和使用,即在Velocity页面中加入一行script标签即可实现开箱即用;

(2)Velocity的页面编写语法与Vue的模板语法非常接近。

混合架构内部,模板渲染需要分两步进行: Velocity模板首先在服务端渲染为Vue模板,Vue模板在客户端渲染为最终页面。

3242c2b35a2d4f4b85cf5459e90f9964~noop.image?_iz=58558&from=article.pc_detail&x-expires=1685498775&x-signature=L8N1mqR%2Bqd71HrKN%2BrBcJgn6Rq0%3D

混合架构存在的问题是,由于一些Session内关键参数是服务器直出,Vue并不能直接获取到这些参数,因此传参的方案是在页面中提前埋了一些占位符,Vue执行时通过访问DOM来获取。

后续需求迭代时,可以逐步将业务逻辑从老旧MVC技术栈迁移到新的MVVC技术栈中,实现开发、维护效率的提升。

二、 建立Velocity单文件组件化能力

当项目规模较大时,不同模块之间可能存在一些相似的功能或逻辑,摆在面前的问题是如何实现模块级的功能复用。

因此第二个步骤是在Velocity系统中引入组件化能力,实现跨页面代码复用。Velocity系统由于渲染依赖Java环境,难以适用基于NodeJs的前端工程化能力,无法直接使用Vue的单文件组件化能力。幸运的是,可以利用Velocity的包含(#include)和解析(#parse)能力,配合Vue的API接口,实现一种创新型的Velocity+Vue单文件组件化技术。

756d597d828b455e9c62edfe320d8eaf~noop.image?_iz=58558&from=article.pc_detail&x-expires=1685498775&x-signature=vlCYdOLy2pYYOuvVwC1Z7E2Je5M%3D

如果你熟悉Vue,你肯定对Vue单文件组件很熟悉了,即一个文件名以.vue后缀结尾的文件,它描述了一个Vue组件,内部结构的三板斧:template、script、style,简单来说分别描述了组件的模板呈现、逻辑交互、css样式。

Velocity单文件组件的组织方式参照了这个层级结构,使用一个文件名以.vm后缀结尾的文件,描述了一个Velocity组件,由于缺乏工程化的能力,区别点在于:(1)为了兼容低版本浏览器,需要使用script标签来承载模板;不考虑浏览器兼容性的情况下,也可以直接使用template标签。(2)需要手动调用Vue.component执行组件的注册。

85ba94b82b0342a6b7b1b319180d2d05~noop.image?_iz=58558&from=article.pc_detail&x-expires=1685498775&x-signature=1ST5qj4qTMbz8KzuZLFf3T6B8RY%3D

实现单文件组件化之后,Velocity页面可以通过粒度更小的组件来层层组装,实现系统的业务耦合程度进一步降低。

三、 创建Velocity本地沙盒环境 + 前端工程化

前面两个步骤对系统整体架构进行了大幅优化,但是仍有一个痛点没解决:Velocity渲染依赖Java环境,习惯了本地开发的前端同学会很无语:改一个小问题需要本地盲开发->在线部署容器->看效果->继续盲修改,一来二去几个小时就过去了。

0e70c32b747f414f910aedb579ecc9dd~noop.image?_iz=58558&from=article.pc_detail&x-expires=1685498775&x-signature=r1fFUCz4h05oeSkFDGk6L91E2YI%3D

因此第三个步骤是实现Velocity本地编译和开发环境,并且引入工程化技术实现热更新。

解决Velocity本地编译的核心思路是模拟Server的环境变量,并且支持Velocity语法编译。我们搭建了一套基于Velocity的前端沙盒工程,前者通过在工程中mock服务端变量的方式来实现,在本地JSON数据源承载这些环境变量;后者是基于Velocity语法AST重构,开发了一套解析引擎Velocity-loader,支持在webpack中实时解析文件并注入环境参数。

沙盒能力引入后,开发流程转变为本地实时开发Velocity,热更新达到毫秒级,开发体验只有一个字:爽。

b437385bcf394311aa216ad369b87f64~noop.image?_iz=58558&from=article.pc_detail&x-expires=1685498775&x-signature=%2BhA2pjmQ%2BFxNKsG2r%2FpncB1CDs8%3D

四、 Velocity页面前后端分离

事实上,对比前三个步骤,我们距离Velocity页面彻底前后端分离已经很接近了。

第四个步骤是真正实现Velocity页面的前端独立构建和部署,并永久摆脱依赖Server端渲染。但由于Vue-loader实际上会在工程编译时把模板语法解析成render函数,已经破坏了模板语法的结构,因此不能支持在客户端动态的解析Velocity,需要固化渲染环境变量。Velocity的动态数据渲染部分需要改写为Vue的语法来实现,托靠客户端Ajax来刷新动态数据和页面。

至此,我们完整实现了对Velocity后端应用向前端工程化逐步演进之路,路漫漫其修远兮,吾将上下而求索,也欢迎各位看官共同探讨。

作者:京东零售 陈震

内容来源:京东云开发者社区


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK