美文网首页前端杂货铺程序员
启嘉网前端架构设计分享

启嘉网前端架构设计分享

作者: Thomas奇 | 来源:发表于2018-02-02 11:51 被阅读342次

本文章基于以下CC协议知识共享:署名(BY)-非商业性使用(NC)-禁止演绎(ND)

本文章的目的、意义和假定条件:

  • 主要目的是记录与总结。
  • 本文的示范项目“启嘉网”是做计算机在线教育的,同时本人列表好友中在校学生也比较多,所以教育和传播知识是另一个目的。
  • 其次是分享技术,希望 Webpack 能更快的在国内普及开。目前大部分能制定前端架构的公司主要集中在一线城市,二三线城市的公司很多是使用一套脚手架解决,甚至脚手架出了问题都不知道如何修改。
  • 希望有更多人能以技术本身作为驱动力。而不是靠着现有的技术固步不前、得过且过。
  • 本文只讨论方案和思路,并不过多的涉及架构设计的具体实现,该部分可参考我的另一篇文章:(还没有写……)

目录


  • 前端技术发展概要
  • 从无到有,如何做技术选型
  • 自动化构建工具的实际应用
  • 构建工具的更进一步是什么
  • 架构复用:抽象通用部分
  • 技术与艺术的结合
  • 总结

前端技术发展概要


曾经有位同学问过我,为什么我大学选择了Java专业,结果却做了一份前端的工作,对他来说前端似乎是一个很低端的职位。而且我们学校的专业划分是需要考试的,Java作为一个热门专业,不是很容易进来。所以,他觉得一直学习不错的我,大学期间“堕落”了。
  但是实际上,前端在近几年的发展可以说是突飞猛进。所以,本文的第一节先给那些还在用原生HTML、CSS、JS写页面的同学补补课了。就简单的说一说目前热门前端技术的一些关键词吧:HTML模板编译、CSS预处理、JS模块化、代码分片、自动化构建工具、数据驱动、组件化开发、跨平台开发、缓存策略、ES6语法……等等。其中针对任何一个关键词去百度搜索,又可以延伸出很多技术点。所以在这里不过多叙述,因为能说的太多了,不懂的同学可以自行百度,或者参考我一年前初入Webpack时写过的一篇稚嫩的介绍文:浅析新版“启嘉网” 前端项目架构 - 简书

从无到有,如何做技术选型


技术选型是最开始的一步,也是非常重要的一步,好的技术选型可以保证项目的可用性、可维护性以及可持续发展的可能。在启嘉网最初从传统的HTML、CSS、JS写页面切换到模块化、组件化、自动化构建时,做技术选型确实很困难,因为开发组中都没有人接触过。为此我做了大量调研,最终选择了 Vue + jQuery + Less + Webpack 的方案(第一版)。之所以这样选择,主要是有以下几点考虑:

  1. Vue 入门简单,更适合当时的开发成员快速上手。
  2. Vue 是渐进式框架,表示我们可以在原有的项目中逐步引入 Vue 代码。甚至在遇到不会写的地方时,使用传统写法替代。
  3. 实际上 Vue 作为一个数据驱动框架,基本上是完全不需要 jQuery 的。但是为了过渡使用,并兼容一些传统的 jQuery 插件。在第一版的前端架构设计时我们依然引入了jQuery。
  4. Webpack 就不必说了,功能强大、主流。实际上在 Webpack 之前,也曾研究过 Grunt 和 Gulp 两款工具,不过并没有实际应用到生产环境。
  5. 为什么不使用 Vue 全家桶(vuex、vue-router)?首先启嘉网是一个多页面应用,业务逻辑分布在各个页面,所以在单个页面中基本不涉及页面路由。同样的,对于单个页面,其业务逻辑就小了很多。也就不需要vuex来管理状态了。我们自己实现了一个单例模式用来存储全局状态。
      虽然上述方案看起来很low,但是却反映了一个实质性的思考过程。在大多数情况下,做技术选型除了考虑能否匹配产品需求外,最重要的应该是考量是否适合自己的团队使用,考虑团队成员的开发体验是怎样的。当然,也不能说这套方案的体验很好,作为第一个架构版本,不足的地方肯定会有。但是相对之前的传统开发模式,我们是进步很多了。要能看到自己的进步,这样才有动力继续学习研究。

自动化构建工具的实际应用


在完成技术选型后,就需要调配开发工具来支持技术框架的使用和项目的开发了,其中自动化构建工具是很重要的一环。构建工具的概念就请各位同学自行百度吧,本文中仅讨论实际应用,在这里就不再赘述了。目前启嘉网的自动化构建工具主要使用 Webpack(以及其他工具)做到了以下几点:

  1. JS模块化:通过 Webpack 处理各个模块之间的引用关系,并通过 CommonsChunkPlugin 将大量引用的模块统一存放到一个 JS 文件中,优化加载速度。
  2. CSS预处理:主要使用 LESS 语法补充 CSS 的不足,并使用 postcss 来抹平 CSS3 在浏览器间的前缀差异。
  3. Babel转义器:稍微了解 JS 的同学应该会知道 JS 的语法标准是基于 ECMA Script 的。同时由于H5标准的制定与发展,ES 在近几年的更新很快。而较新的语法和特性在旧版本浏览器上是无法执行的。所以我们通过 Babel 转译器将 ES6、ES7 代码转译成 ES5 的写法。这样,我们就可以再开发时愉快的使用各种新特性,例如 Class、Promise、Decorator等,同时浏览器还可以正常执行代码。
  4. 将公用库从代码中抽离,使用CDN减少代码体积、优化加载速度。
  5. UglifyJsPlugin:该插件可以对JS进行压缩混淆,减小代码体积。
  6. 代码热更新:在开发过程中保存文件时,使浏览器自动刷新,方便查看修改效果。并且在修改一些JS代码或CSS样式时,只会单纯的替换掉被修改的部分。而不会让整页刷新导致状态丢失。
  7. 开发时反向代理:这一步是前后端分离时导致的跨域问题,因为分离后所有接口均通过AJAX请求,并且开发时客户机与服务器不同域而出现这个问题。故使用 Express 的 express-http-proxy 中间件就行反向代理,将前端请求转发到后台服务器。
  8. 源映射:Source Map 是 JS 进行模块化后产生的问题,由于 JS 源码在浏览器里运行之前,经过了一层编译。导致调试时无法追踪到 BUG 在源代码中的位置。所以使用源映射记录下编译前后的代码映射关系。
  9. 断点调试:使用 Source Map 后我们就可以在浏览器中进行断点调试了,或者借助一些编辑器插件(如:VSCode Debugger for Chrome),我们就可以在编辑器中加断点并捕捉错误了。
  10. ES-Lint:代码规范化插件,可以约束不规范的代码,并在编译前排查语法错误。
  11. NightMare E2E测试框架:其实最开始启嘉网搭建过一次 NightWatch 框架,配置挺麻烦的,结果搭建好了却没有人愿意写测试代码,再加上当时工作中有其他事情,也就没有时间去管理,想了想可能还是时机不成熟吧。到了最近我们改成了NightMare框架,准备强制要求写测试脚本了。
  12. HappyPack:多线程编译,提高编译速度。
  13. DllReferencePlugin:依赖库预编译,提高编译速度。
  14. Webpack Bundle Analyzer:包分析工具,用于分析包引用并进行优化。

构建工具的更进一步是什么


上述内容可能看起来很多,但是实际上只能算是完成了架构设计中比较基础的部分。因为构建工具并不是架构的全部,在构建工具之外、在构建工具之上的东西,才是前端架构的核心意义。
  纵观前端(构建工具)的发展史,我们可以看到层出不穷的工具一大部分都是在做优化开发体验的工作。虽然程序的运行效率很重要,但是在大部分的应用场景中,架构都会使用主流的社区方案。所以各个架构的构建工具技术上基本大同小异。真正造成差异化的其实是开发体验。
  下面的内容阐述了,在启嘉网中部分开发体验优化的方案。

完善公用库及文档

在开发中必定会用到一些整个项目代码都会用到的通用方法,随着公用库越来越大,如果无法做到及时添加标准、漂亮的注释,项目代码会很快腐烂。在启嘉网,我们使用JSDoc规范来编写注释。并在构建工具运行前,自动根据注释编译成文档页面,然后自动打开,供开发者查阅。

根据JSDoc注释生成的文档 根据JSDoc注释生成的文档

开发者工具

在启嘉网的开发环境下,我们开发了一套工具来辅助前端调试应用数据。希望能做到在大部分情况下,不通过浏览器开发者工具,就可以更针对的获取想要的调试数据。当然,开发这样一个工具可能会投入大量的时间,但是我觉得这是值得的。

开发者工具演示GIF

编写语法提示脚本

虽然,JSDoc的文档已经非常全面了,但是不停的翻文档也是非常麻烦的事情。所以我们使用d.ts来描述项目公用库的方法,在使用 VSCode 编辑器时,可以自动提示公用库的方法并显示注释。

代码语法提示

控制台视觉效果

这部分是一个追求工匠精神的过程,在编写构建工具脚本时,我用了很长时间来封装一些基本类,即便是非常不起眼的控制台窗口,我也在呈现上下了很多功夫。

自己编写的Log控制台输出类 使用 friendly-errors-webpack-plugin 优化错误呈现的视觉效果

总结

开发体验的优化方式还有很多,在这里不再细讲了。因为只要思想正确,你总能想到不同的优化方案。方法是死的,人是活的,要学会自己思考。在启嘉网中,最基本的原则就是:“对开发人员屏蔽底层细节,在不过分影响开发人员习惯的情况下,渐进式的增强体验。”

架构复用:抽象通用部分


随着公司的产品线越来越多,构建工具搭建的次数也多了。逐渐的我发现在技术上能改动的地方越来越少了,每次的架构设计,基本都是在复制粘贴。所以我开始关注构建工具的通用部分,并抽离形成一套标准方案。
  这样做其实有很多好处,一是节省时间,二是开发人员在各个项目中能使用一套熟悉的环境。虽然技术框架可能不一样,有的用 Vue 有的用 React ,但是味道还是那个熟悉的味道。
  实际做法如下:

制定清晰明确的目录结构

这点应该是很简单了,目录结构清晰合理,确保在各个不同的项目中,也不会有太大的改变。比如 html、js、css、components、modules 放在 Page(页面) 中。Webpack 编译脚本、公用库、配置项放在指定的目录中。这样团队开发人员用的多了以后,就能逐渐熟悉各个目录的内容了。

模块按需加载

有的项目用到了 Express 同时做开发服务和接口,有的项目直接用 dev-server 启动,还有的项目用到了一些其他技术,比如 GraphQL、Socket.io 等。为了能快速了解项目使用了哪些服务,并能灵活的管理。我们写了一个模块加载类,然后通过列表配置进行加载管理。
  这样,我们几乎可以把整个服务写成低耦合模块。然后进行复制时,整个服务可以快速的迁移到其他项目中。

模块按需加载

总结

通用化这部分的工作其实刚刚开始做,目前还没有更多的方案。我觉得这是一个逐渐积累和沉淀的过程,目前其实还有一些想法,只不过还没有时间去实施。当实际应用后,我再来补充这篇文章吧。

技术与艺术的结合


狭义的艺术

狭义的来说,艺术其实是指UI。因为作为前端开发人员,接触最多的实际上就是美工的设计图了。但是如何准确还原设计图、并高效的和美工进行沟通,实际上也是前端架构可以解决的问题。
  实际上很多前端开发的概念,是和设计通用的,在多年的开发过程中,美工和程序共同总结了很多通用方案。比如栅格系统、组件化等等。
在启嘉网中,我们将设计规范中的栅格系统、颜色、字号等等一系列内容,都写进了 LESS 变量和方法中。同时自己维护了一套基于设计图而开发的组件库。在这些工作基础上,大大提高了前端开发和设计师出图的效率。

广义的艺术

广义的来说,艺术指的是整个开发流程中的方方面面。例如,虽然构建工具极大的方便了开发人员,但是在部署时需要一系列编译、更新等操作,仍然是很麻烦,所以启嘉网自己开发了一套基于 Docker 容器的部署工具,只需要一个按钮,就可以实现代码的下拉更新、编译、部署等操作。
  这些地方,需要有细致入微的观察,和偏执的工匠精神。不要只是单纯的复制别人的方案,不要只看表层的东西直接拿来应用,要学会自己思考、总结。去体会开发人员的开发过程,然后做出改变。做每一件事都要像工匠一样,做成艺术。

总结


这份文档基本总结了过去一年我在前端方面做出的努力的概述,唯一的感受就是钻研技术时除了有深度还要有广度。我所做的前端架构,不光光是紧盯前端社区看出来的,其实还有很多其他技术做支撑,例如过去一年在 Docker 上也学习了很多,对我的帮助也很大。简单地说就是,你在广度上看的越多,在深度上就能看的越远。
  文档的不足之处也有很多,如有误人子弟之处欢迎评论斧正。写技术文档确实很累,要考虑通俗易懂、还要能表达真材实料。最后的收尾可能有些草率,有机会再补充上吧。到这里已经6000字了。手酸。
最后,如果本文对您略有帮助,也欢迎在下方给我打赏一杯咖啡。

相关文章

网友评论

    本文标题:启嘉网前端架构设计分享

    本文链接:https://www.haomeiwen.com/subject/txgszxtx.html