聊聊前端工程化的实践与未来

百家 作者:InfoQ 2018-04-21 02:16:12


作者 | 王若林
出处 | 公众号 EAWorld  
1 前端过去一年的发展

2017年的前端发生了非常多的事情。快速的技术进步,似乎已经使前端工程师应接不暇,我们来一起看下去年发生了哪些事件:

  • React16发布前夕,React license风波发展到顶峰,多家公司宣布将不在使用 react作为其产品的前端框架。网上对 Facebook的声讨也达到了顶点。随后 Facebook不得不将 React license更改为 MIT。这件事情极大的影响了 React在大家心中的定位,人们纷纷将目光投向 Vue。

  • 去年,Angular一口气发布了两个版本,Angular4以及 Angular5。这样的变化似乎在意料之中,又在意料之外。根据官方文档说明,从 Angular4之后,每年只会发布一个大版本。然而在刚刚进入 18年的时候,Angular 6.0.0 Beta版本发布,让前端开发者不得不感慨,前端之路太心酸了。

  • 2017年是 Vue飞速发展的一年,除了学习曲线平缓,Api简单易用之外等诸多原因外,离不开 React和 Angular的种种“不友好”的行为。

  • PWA(渐进式网页应用)越来越被大家所关注,也越来越被应用。也许这个技术并不是我们一直在寻找的使用网页技术完美支持其它客户端的方法,但 PWA使用现代的浏览器技术使得访问网页应用的体验和原生移动应用一样。并且在性能上有了大幅度的提升,而且支持离线访问,像推送通知这样原生 APP才有的功能也支持了。

  • WebAssembly(wasm)已经开始被所有主流浏览器支持。也许 WebAssembly将会开创 Web的 VR/AR新时代。

  • 2017年 Serverless应用持续增热,这是一种新的可以提高性能又减少资源耗费的架构。你的客户端完全从服务器从分离出来,这样就可以只关注应用本身而不是架构。一个常见的实现方法是用 AWS API Gateway和 AWS Lambda函数作为后台服务。

  • GraphQL日趋火爆,有胜过 REST之势。Samer Buna甚至宣传 REST已死。GraphQL允许客户端自定义数据,然后一次获取。而 REST方案需要维护获取很多无效数据。Github的新版 API已被 GraphQL重写。

在变化飞快的前端发展中,前端究竟应该如何开发,究竟应该用什么框架,前端代码如何部署,如何进行前后端分离成为人们争论的焦点。

2 工程化是前端实现的核心

在未来,前端工程化成为工程师关注的核心问题。 而工程化的几个重要方面,就是路由的实现方式,组件模块化,构建自动化。

  • 路由实现方式。前后端分离,前端路由显得尤为重要。除了多层级的设置,还要考虑路由实现方式。

  • 由于前端模块化,各个组件各个模块如何相互通信,则尤为重要。必须统一进行管理,否则在多人同时开发,且页面不断增加的情况下,前端代码会越来越难以维护。

  • 开发的过程中,要考虑到部署方式。尽量使用一套能够满足所有部署方案的方法进行开发,减少部署工作量。

路由实现方式

最常用的路由分为 Hash路由及 History路由。

  • Hash路由:(例 http://primeton.com/#/login.html)通过改变地址后面的 hash来改变浏览器历史记录,Hash部分不会发至服务端,框架本身根据 url来生成相应的模块

  • History路由:(例 http://primeton.com/login.html)使用 HTML5的 History API,提供 pushState(),replaceState()等方法。路由请求会发至后端服务器。

一般主流做法推荐使用 History路由。

使用 History路由的好处在于两点,其一是页面 url比较美观,其二是可以复用浏览器自身的前进后退特性,但在 SPA(单页面应用)情况下支持 history模式需要后端的支持。

由于普元微服务治理平台并不希望路由变化时,浏览器发请求到后端,故使用 Hash路由。这样做的好处是通过前端控制用户权限,一定程度上方便后期对系统的扩展。这主要跟整体平台架构的设计有关。

灵活部署,解决前后端通信

前后端分离模式的开发模式下,通常有两种部署方式来解决与后端进行 ajax通信的问题。一种是 Nginx作为部署容器,一种在构建工具中将请求转发。

  1. Nginx作为部署方式,需要启动一个 Nginx服务,通过配置 config文件,将请求转发到不同的地址。

  2. 若以构建工具的方式,则是通过构建工具启动的 server自带的 proxy将请求转发出去。

接下来详细介绍使用构建工具转发请求的方式。

以 Webpack为例,通过 proxy,Webpack server会过滤请求,将带有配置的路径的请求,转发到需要转发的服务器。

当代码需要部署在 tomcat中时,由于不同项目在 Webapp中的前端文件名称可能不同,每当 Webapp中的应用更改名称,前端都需要更改 ajax的路径,非常麻烦。

有一种方法可以一劳永逸的解决这个问题。使用 NPM build之前,在你的 package.json文件中,加上 homepage变量来写明你的服务的绝对路径。

npm在 build的过程中,默认前端代码就在服务的根路径下,想要重写这个路径,可以在 package.json中加入上面的 homepage,便可重写。若不想设置固定的路径,则可以用下图实例:

3 EOS8前端工程化设计实践分析

以我们的技术团队目前正在研发的 EOS8的前端设计为例,讲一讲前端工程化的实践。

EOS8平台的目标是提供一整套微服务应用平台与应用全生命周期管理平台,能够提供企业快速构建数字化需求交付的能力。

EOS8与我们正在研发的另一款产品 DevOps都遵循前后端分离、前端模块化的开发方式进行开发。这样做的好处是能够方便多地同事同时进行开发,减少沟通维护成本,同时保证后期的可扩展性。另外,前后端分离,也是微服务系统比较好的实践。

抛开框架之争,结合 EOS8的前端设计,来分析从开发到部署的整个生命周期过程,主要从以下三点来考虑:

  • 需要根据需求,考虑清楚页面的路由实现方式,同时从功能角度具体分类各个功能模块。

  • 由于平台功能的可添加性非常强,故页面设计需要符合模块化设计,方便后期添加新的功能模块,同时在开发的过程中,需要将 ui组件公共化,标准化,方便后期开发。

  • 前端代码的架构要考虑最终上线的部署方式,同时也要方便开发人员进行开发。

模块化开发

首先,前端工程化的第一步,要先划分清楚前端的功能模块。功能模块之间不能耦合。这样的好处是,不同团队可以同时进行开发,最终将各自开发的模块合入即可。模块的开发遵循统一的开发标准。数据可以通过 flux来管理。

我们作了如下的模块划分:

  • 平台状态监控。

  • 用户认证,组织机构管理等。

  • 应用节点配置进行更改,并进行灰度发布等。

  • 应用下各个状态的监控。

  • 不同应用进行统一管理的能力。

  • 对应用提供 Api Gateway。


模块化路由及页面设置

在这里,模块化主要从路由模块化和页面模块化两个方面来设计。

路由模块化,可以解决父子模块嵌套问题,在单向数据流的框架中,这一点尤为重要。同时,通过路由嵌套,规范页面 URL,使整个前端路由清晰,具有方便跳转、传参等优势。

页面模块化则可以提高页面组件的复用率,减少重复的代码。

路由模块化:整个平台可以分为 6大模块,每个模块分配一个路由地址,通过路由地址找到不同的模块。图中展示的是一级路由地址,如下图所示:

页面模块化:就单个页面而言,页面需要按照组件的方式组成。为了能够减少组件的复杂性,,可以划分为 Container Components以及 Presentation Components。

1、Container Components主要用于承载各个不同的公共组件,起到一定布局的功能。同时,他负责与服务端进行通信,获取页面所需的数据,传给 Presentation Components。

2、Presentation Components主要用于具体的功能组件。它一般不参与数据的交互,只负责展示 Container传给他的数据。这样可以达到最大的复用这个组件

如图所示,页面由 Header,SideBar,Content三个组件组成,而每个组件,可由多个小的公共组件组成,如下图所示:

部署实践  

在这里,模块化主要从路由模块化和页面模块化两个方面来设计。

路由模块化,可以解决父子模块嵌套问题,在单向数据流的框架中,这一点尤为重要。同时,通过路由嵌套,规范页面 URL,使整个前端路由清晰,具有方便跳转、传参等优势。

页面模块化则可以提高页面组件的复用率,减少重复的代码。

路由模块化:整个平台可以分为 6大模块,每个模块分配一个路由地址,通过路由地址找到不同的模块。图中展示的是一级路由地址,如下图所示:

前端部署的方案有两种:

  • 前后端分离方式,通过 nginx转到后台。这种方式不需要关注前端文件的路径问题。

  • 混合模式下,前端代码会放到 tomcat中,Ajax以及静态资源需要关注路径问题。

图中左侧为前后端分离的简易方案。具体部署时,通过 nginx,可以进行负载均衡,同时可以部署多台 nginx服务器。如果性能仍旧无法满足,则可以使用 LVS+F5/LVS+Nginx等多种方式进行负载均衡。

图中右侧为最传统的部署方式,将前端编译工具打包出来的文件,放入 tomcat中即可。

不同应用场景下,负载均衡的方案有很多,要根据实际的应用场景来选择适合自己的方案。这里我们的前端架构,只要在打包时,根据不同的部署方案,将前端文件的路径问题、ajax路径问题解决即可。

4 展望与总结
展望

微前端这个术语,最初来源于 ThoughtWorks公司的技术雷达。传统的微服务架构下的前端:

微前端的核心思想如图所示(图片来源于网络)

微前端的理念,是将一个网站当成一个组件的合成体,每个组件由一个独立的团队负责。带来的好处是每一个团队在选择和升级他们的技术栈时,并不需要与其他团队进行统一,同时代码不依赖于共享状态和全局的变量。

这听起来很美好,不过目前微前端大体上还停留在概念的阶段,具体实施起来困难重重,光是框架之间的壁垒,就难以突破。

也许在某天,技术大牛们终将打破技术的壁垒,实现微前端,让我们拭目以待。

总结

通过前端的展望,可以看出来,在未来,框架将不再限制前端架构,不再制约前端开发人员。人们可以根据自己的业务,选择不同的框架,最后将各个业务模块组合起来。人们需要关注的核心,是如何将前端工程化,如何合理的将业务模块化、如何合理的分配路由,如何更快的进行开发等。

无论采用哪种前端框架,前端开发的本质思路是一样的。学习前端,搭建前端项目,不应只关注具体的框架,更多要从前端工程化的角度出发去实现项目。这样才能使前端项目拥有更短的开发周期,更好的用户体验,更绚丽的页面效果。

作者介绍

王若林,普元 SOA&云计算部门高级前端工程师,曾在 Tibco以及海航科技担任前端工程师,参与开发 Tibco Api Gateway、海航商店、海航 IAM等项目。现主要从事普元 EOS微服务管理平台开发设计工作。


期望得到更多优质技术干货,欢迎加入 EAWorld社区,与近万名技术人一起成长。入群暗号:421

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接