Java全栈开发 - 前端技术更新换代之路

2019, Dec 24    

我刚开始接触Java的时候主要web端框架是Struts,那时还没有什么前后端分离,还不太流行MVVM框架。 作为一个Java程序员,懂得最多的还是如何用jsp+jquery+easyui来写一个OA系统,需要知道如何一些tomcat的配置,还有对于服务器的一些操作等等。那时的全栈工程师,就是Java+jsp+配置工程师,配置主要是Spring+Struts+ibatis的大量xml配置。套模板,写脚本,复制粘贴easy-ui上的组件代码等。以Java为主的后台系统开发体系中,基本没有专门的前端岗位,都是后端开发全包的这样一个状态。

那时候中小型公司都不会招专门的前端,如果真的需要一些比较复杂美观度要求比较高的页面,可能会将这部分开发工作外包出去,后端程序员再将写好的前端页面复制到项目中改成jsp,其中一些内容替换成jsp标签,在调整一下Javascript交互等等操作,一个项目就可以进入测试上线了。在当时,这就是大多数Java程序员的开发模式。

对于Struts中的一个Action成员变量多如牛毛,引用的地方不计其数,改一处动全身,再加上爆出一些严重的漏洞情况下。SpringMVC开始异军突起,注解式的路径映射,以方法为单位的请求处理,简洁明了的请求定义,开发易上手,易操作,很快的让人开始慢慢抛弃Struts,投入SpringMVC的怀抱。从Struts到SpringMVC的转变中,也只是web层后端框架的选择,开发模式还是和以前一样,前端工程师帮忙做些页面,后端将其转成jsp。然后打成war包,部署到tomcat上,开发流程就完了。

在jsp为主的模板类渲染开发流程下,一个页面请求的渲染如下图:

sequenceDiagram 浏览器 ->> Nginx: 发起请求 Nginx ->> Tomcat: 转发请求 Tomcat ->> Servlet: 解析请求 Servlet ->>+JSP: 请求处理,取出需要的数据交给JSP进行渲染 JSP ->> Servlet: 返回渲染后的JSP内容 Servlet ->> Tomcat: 返回响应结果 Tomcat ->> Nginx: 返回响应结果 Nginx ->> 浏览器: 返回响应结果

随着技术发展的不断提高,前后端分离的开发方式开始慢慢流行起来,在有机会开始独立带领一些项目情况下,开始尝试使用前后端分离的方式进行开发。刚开始的时候,只是将jsp替换成了纯html文件,所有的请求用ajax来处理,打包和发布的方式还是和以前一样,都是打在同一个war包里面,丢到tomcat里。当时觉得,这种开发方式的理念很好,但是开发起来很麻烦,后端同学的大部分前端技术水平有限,习惯了jsp标签开发方式,转变为大量使用ajax和js脚本来渲染数据,开发复杂度在转换初期,上升了不少。

磕磕碰碰写了一段时间,前端水平有所提高,工具用的越来越熟练,利用一些面向对象的思想开始在前端进行开发。开始封装一些封装内部工具,例如渲染表单,自动绑定表单,表格渲染之类的,也算是顺利的过渡到了前后端分离的初期阶段。随着前端团队的慢慢组起,小组可以开始独立的完成一些页面,不需要后端同事再来参与,只需要沟通好接口即可。前后端分离的好处凸显了出来,极大的减少了后端开发人员,特别是一些不擅长html+css的痛苦,工作效率有了很大的提升。人员的分工也开始更加明确,各自专注于自己的领域,工作效率有了一定的提升。

在这个阶段,一个页面请求的流程有了些许改变,页面框架的直接由静态资源提供,然后通过异步的方式进行数据请求,将请求结果用js脚本进行渲染,很大程度减少了jsp编译渲染的耗时,相对于之前的流程,前后端分离的模式,用户体验上有了不少的提升

sequenceDiagram 浏览器 ->> Nginx: 发起请求 Nginx ->> Tomcat: 转发请求 Tomcat ->> 静态资源: 查找静态资源html等文件 静态资源 ->> Tomcat: 返回文件内容 Tomcat ->> Nginx: 返回内容 Nginx ->> 浏览器: 返回内容 浏览器 ->> 浏览器: 页面渲染,并执行脚本 浏览器 ->> Nginx: 发起异步ajax请求 Nginx ->> Tomcat: 转发请求 Tomcat ->> Servlet: 转发请求 Servlet ->> Servlet: 解析处理请求 Servlet ->> Tomcat: 返回响应结果(通常是JSON格式) Tomcat ->> Nginx: 返回响应结果 Nginx ->> 浏览器: 返回响应结果 浏览器 ->> 浏览器: js脚本构建页面

SVN在当时,是很流行的版本控制工具,作为一个中小型的项目,当时主流的开发方式就是一个分支走到底,发布版本的时候,不是在解决冲突就是在解决冲突的路上。就这样我们开始将前端的部分单独抽离出来,作为一个单独的项目,独立以及发布。但是随着模块越来越多,功能越来越多,也避免不了单分支开发的弊端,又受不了SVN的分支一开就是半天,很多人代码都不敢提交,因为发布的时候,是单分支操作的,可能会影响到需要正式发布的代码,所以大家的代码都只是在自己本机上,协作起来不是很方便。我开始在团队中推广使用GIT作为版本控制工具。专门整理了一些资料,做一些简单的培训,让大家知道分支的概念,使用,和多分支的开发方式,以及一些流行的工作流。很多人是首次使用GIT,用的时候磕磕碰碰,很不习惯。

切换工具就是这样,刚开始换的时候肯定不习惯,毕竟需要掌握新的命令以及转换原有的开发理念。从原来闭着眼也知道怎么提交版本的SVN转换到要敲好几个命令才能提交完成的GIT,再加上从单分支到多分支工作流的转变,很多人当时还有些抱怨说太复杂了。对于这种情况,没办法,时间是解决问题的根本,随着大家对工具的熟练程度提高,慢慢的,都会习惯的。

再说回前后端分离,随着nodejs逐渐流行,原有纯手写静态页面的前端工程师开始有了些许变化。最开始使用less/sass工具作为css的预编译器,jade/pug来进行html标签部分的开发,后来使用gulp,进行工作流的管理,慢慢的前端也开始走向简易的工程化的方案,预编译,混淆,压缩,构建,打包一气呵成。就算到这个时候,使用的前端库也慢慢从以jquery/zepto为主的dom操作为主的库进行多页面开发,逐渐转变为React/Vue等MVVM框架进行SPA开发。

由于技术发展果快,对于后端程序员来说涉及该部分需求过浅,模块化解决方案也是用了Vue才开始上手了解的。对比React和Vue,我个人还是比较喜欢Vue进行开发,简单易上手,逐渐将公司技术端全转向Vue来进行前端开发。逐渐抛弃原有的html内混用jquery+vue的开发方式,由原来的所有组件复制粘贴的开发模式,转变为,以组件为基本单位的开发方式。

使用webpack带来的好处显而易见,除了配置有些繁琐之外。但是在使用vue进行开发的情况下,vue-cli工具已经提供了很多预置的配置,作为开发这边只需要配置好一些关键参数就可以,而且也不会一直去改这个配置。习惯了热重载,自动编译,数据绑定的开发模式,再加上丰富的开源组件库,以及es5,es6的一些新语法,前端开发起来越是得心应手。

在这个阶段微服务等概念已经开始流行起来,Java以Spring-boot为主的各式扩展,雨露春笋般的冒出来,基于前后端分离后,不再需要jsp,静态文件也不需要打包在后端代码包中。每一个Spring-boot微服务都是一个自带tomcat的jar包构成,使用命令行即可启动,方便至极。

到这个阶段,前端项目被剥离出来,可以独立部署,不再依赖后端发布,前后端项目彻底分离,不再互相依赖和影响。前端可以独立于后端单独运行,开发时对于接口访问也可以自行mock,在这阶段后端开发只需要定义好接口文档,前端可以独立进行开发,不受后端开发进度影响。

这阶段请求处理的流程如下

sequenceDiagram 浏览器 ->> Nginx: 发起请求 Nginx ->> 静态资源: 查找静态资源文件 静态资源 ->> Nginx: 返回文件内容 Nginx ->> 浏览器: 返回文件内容 浏览器 ->> 浏览器: 页面渲染 浏览器 ->> Nginx: 发起异步ajax请求 Nginx ->> 微服务集群: 转发请求 微服务集群 ->> 微服务集群: 解析处理请求 微服务集群 ->> Nginx: 返回响应结果(通常是JSON格式) Nginx ->> 浏览器: 返回响应结果 浏览器 ->> 浏览器: js脚本构建页面

前后端分离是趋势所在,技术更新换代更是无时无刻不在进行。就像Typescript慢慢替代Javascript成为前端首选,Serverless的概念开始被投入生产使用。保持自己的技术跟得上时代,能够及时接纳变化和学习包容,才是提升自己核心竞争力的所在。愿共勉