整个《前端分层架构实战》分成两部分:

  1. 前端分层架构实战(一):分层架构问题分析和结构设计
  2. 前端分层架构实战(二):分层架构项目规划和工程实施

本文是其中的第一篇。

随着微服务兴起前后端分离架构的越来越流行,前端的负责的开发任务越来越重,功能复杂度和代码量也越来越高,在同一个项目投入的前端人力也是越来越多,这个时候需要我们使用更加高效的方式来组织我们的代码结构。目前前端有很多框架帮我们做了很多这方面的工作,比如目前比较流行的的三大框架:angular、vue、react。但是我们在实际使用的时候往往发现,使用他们的命令行工具生成了一个工程,可以进行开发了,但是真正应用到真实项目中的时候,往往有力不从心的感觉,特别是企业及的项目中,这是由于它们做的只是从技术层面上解决了代码组织方式,并没有给出结合业务时项目里的组织结构和组织方法。而这些正是软件架构所解决的问题,软件架构正在后端开发中大放异彩,那我们能不能也在前端开发中引入软件架构方法,来解决前端日益复杂的开发需求呢?答案是肯定的,下面简单说一下我自己在这里面的实践总结,由于个人能力有限,有不正确的地方欢迎大家指正。

先从我们实际看到的页面效果出发,对我们页面的内容进行分析、设计。以下 2 中页面是我们最常见页面结构,一个是 PC 端常见的页面版式,一个是移动端常见的页面版式,列举这 2 个的目的就是说明在分析层模式的时候,对于 PC 端和移动端都是适用的,也说明我们移动端的页面也在往不断复杂的方向上发展。

img

pc 端

img

移动端

这个是页面展示是呈现的具体效果,那我们如何对其进行分层设计呢?试想如果我们看到的浏览器页面是有厚度的,上面的图是我们正对浏览器看到的页面效果,如果我们从斜上方去看我们的这个页面会是什么样子?。以下是一种简单的划分设计方式,这个层的划分是按照 HTML 的逻辑功能划分的,属于 HTML 逻辑层结构。

img

以上层的拆分是我们在浏览器里面看到内容分层。其实大家所熟悉的 CSS 逻辑层结构划分也是这样的,也即是说 HTML 和 CSS 共享逻辑层结构。这是是正确的,因为界面的呈现使用 HTML 和 CSS 共同完成的,所以它们应该共享相同的逻辑层划分。其实这个层逻辑结构就是通过 CSS 的 z-index 来实现的。其实在我们实际规划 CSS 和 HTML 逻辑层的时候,往往比上面会多一些,一般是4~5层,比如下面是项目中可能存在的一种划分方式

img

在开发的项目工程中物理文件组织是没有按照这个逻辑层去组织的,如果按照逻辑层去组织的代码,当项目代码逐渐增多时代码管理起来将会非常麻烦,并且这个逻辑层结构并不适合 JS 代码结构划分,也并没有包含底层框架、项目管理和代码重用等方面的相关内容。这就要需要我们在项目文件物理存储这个层面上需要有新的层划分方式,这个时候我们将以 JS 角度出发,重点关心项目结构和文件组织方式,方面团队协作和长期维护等需求。以下层架构框图展示了项目中的一种可能划分,也是我们目前的项目结构

img

整个代码功能上划分成 5 层,6个不同的功能块。当然这几个功能块并不是完全相互独立的,会由于基础框架的选型影响所有其他功能块的实现方式。

  • 框架层:这个是最底层,包含最基础的依赖组件。我们常说的 angular、vue、react 包含在这个层级里,这里面基础框架的选择会对其他每个层造成重大影响,并且上面所有层的实现都会基于此做设计。
  • 工具层:是基于框架层选型开发的一些通用公共组件(比如:对话框、警告提示、加载、上传等)。这里的组件可以是自己开发,也可以是使用三方封装,可能还会包含一些和具体业务相关的公共组件。
  • 容器层:负责处理一些公共逻辑和存放公共数据(比如:页面启动流程、用户数据、页面状态数据等),一个系统往往只有一个容器,当然也可以有多个。现在大多数页面启动流程都会比较负责,如登录流程、权限处理等都会和页面启动流程相关,且用户的登录数据、页面的状态信息都需要全局、多模块共享。
  • 视图层:是在容器层上将页面上的可视区域划分成不同的作用的显示区域。在每个显示区域都可以放入不同的内容,并且可以根据用户操作进行切换。针对不同终端的响应式规范,也是在这层进行定义。一个系统或网站往往会有多个不同的视图
  • 内容层:是实现具体业务的层面,我们实现的每个模块都属于内容层的一个内容块。每个内容块都可以放入任意一个视图中,当然在实现内容布局显示的时候,要符合相应视图定义的规范。具体某个内容放入哪个视图中,可以做成动态配置(比如:使用 angular 时,可以选择通过路由配置),这样做到模块级重用。
  • 管理工具:是对工程进行管理的工具,包括打包、依赖管理、单元测试、CI/CD等。这里的选择也会很多,且和我们具体的业务结构相对独立,流行的有 gulp、webpack、grunt 等。

这里除了框架层和容器层需要同步加载,其他所有层的内容都可以做成按需延迟加载。每个层和层里面内容所涉及到的所有资源(JS、CSS、HTML、Image) 都放在相同的目录中,减少开发过程中开发人员的心智负担。