成为一名前端架构师

前言

你是一位经验丰富的前端开发,你的经验和能力在不断成长。有一天,公司决定任命你为前端架构师。你踌躇满志决定大展身手,然而,一个问题困扰了你。css

什么是前端架构,前端架构师的职责是什么?html

今天,让咱们从多个角度来看看什么是前端开发,什么是前端架构。前端

前端开发是什么

首先,让咱们来回顾一下近年来前端开发所走过的一些历程,了解什么是“前端开发”。vue

三驾马车

HTML、JS、CSS是前端的三驾马车,是前端最重要的组成部分。html5

HTML是前端的入口,一切从浏览器加载HTML文档开始。随后浏览器解析HTML文档,并加载相应的JS与CSS文件并解析执行。node

CSS负责修改文档的展示样式,JS则经过侦听用户行为、修改文档内容以及修改元素展示样式来提供丰富的内容展示以及用户交互行为。react

DOM & BOM

DOM(文档对象模型)和BOM(浏览器对象模型)是浏览器提供给JS的一系列接口。JS能够经过这些接口与浏览器/文档交互,例如添加用户交互监听、修改文档内容等等。webpack

DOM包括与文档相关的接口,例如查找元素、遍历文档、修改文档内容等。BOM则提供了许多其余的功能,例如添加定时器、获取当前页面地址等等。ios

ECMAScript

ECMAScript是JS的标准,JS是ECMAScript的实现与扩展。从ES6版本开始,大量新特性的加入与演进,标志着JS的发展进入了一个新的时代。css3

对于一个新特性而言,将经历如下几个阶段:stage0(内部提议)、stage1(正式提案)、stage2(规范草案)、stage3(候选,部分浏览器已经实现该功能并获取用户反馈)、stage4(就绪,进入下个版本的ES规范)。

ES6+的出现为JS引入了许多优秀的语言特性,例如let/const提供了更好的变量/常量申明方式,Promise/async/await解决了回调地狱问题,class提供了更好的面向对象范式,ES modules提供了模块化的新标准。除此以外还有Proxy、Symbol、Map/Set等等特性一样值得关注。

浏览器

浏览器是前端的主要载体。浏览器主要包括用户界面、渲染引擎、JS引擎、网络、数据持久层等组件。

nodejs

nodejs使用了JS的语法规范,并在其上提供了包括网络/文件IO在内的系统交互能力。官方的nodejs是构建在Chrome v8引擎上的JS运行时。

npm最初是针对nodejs设计的依赖管理工具,而现在npm/yarn已经统一了web与nodejs的包管理。

web2.0

web2.0表明着门户网站向网站应用的转型。网站应用提供丰富的交互并且仅静态的信息展现。UGC(用户生成内容)的大量产生也是web2.0的标志之一。

这一时代标志性的技术包括jQuery、AJAX和先后端分离。

jQuery大大下降了浏览性兼容性带来的开发成本,同时sizzle提供的以css selector查询元素的方式大大提升了前端开发效率。随之而来的是构建在jQuery之上的前端组件库的大量出现,大大丰富了前端交互的可能性。即便随着新API的出现和浏览器兼容性的提高,现在jQuery已非主流,但其链式(fluent API)、集合操做、事件代理、构造函数重载等设计模式的灵活应用仍然值得咱们学习与借鉴,更不用sizzle和jQuery对于前端发展的巨大推进。

AJAX容许前端向后台发起异步请求并更新数据,打破了本来必须向后台提交表单并最终请求新页面的模式。在以后的日子里,SPA(单页面应用)应运而生。

而在AJAX以后,web socket和web RTC进一步扩展了浏览器与服务器的通讯方式。前者赋予了web实时通讯的能力,然后者提供了实时语音/视频的功能。

随着前端库的大量出现、前端交互变得愈加复杂,先后端分离的概念开始兴起。从总体的架构视角来看,这对应的是软件分层架构(表现层,业务层,持久层等等)的出现。如同康威定律所述,人员架构也在相应变化:前端开发、后端开发、DBA等等。

页面模板的编写慢慢从后端开发手中交到了前端开发手中,在此时,包括handlebar、mustache在内的基于字符串拼接的前端模板库出现。

HTML5 & CSS3

HTML5表明HTML规范的5.x版本,与2008年发布正式版,与2014年最终定稿。因为其发展历程与移动互联网高度重合,H5一词渐渐成为了“移动web网页/网站/应用”的代名词。

HTML5规范为web带来了许多新特性,包括更多语义化的标签,更丰富的表单项,canvas/WebGL,多媒体(web、audio)、地理定位、数据存储(localstorage、web SQL)、多线程(web worker)等等。

而与2010年正式推出的css3规范一样带来了media query、圆角、渐变、阴影、变形、动效/动画等一系列新特性。

为了应对纷繁的手机屏幕尺寸,media query与box-sizing、rem分别推进了响应式和自适应两大设计理念的发展。同时为了应对兼容性不一的问题,相似Modernizr、html5shiv这样的工具也应运而生。

HTML5与css3的诞生使得移动web开发如虎添翼,多媒体、富交互时代正式来临。

依赖管理

随着前端代码愈加庞大,一个交互复杂的页面极可能包含大量依赖。要管理并理清这些依赖(js、css)并不容易。

面对这一问题,bower和require.js应运而生。

bower是面向web的包管理工具,经过bower咱们能够追踪项目依赖库,并在新环境下检出项目时一键安装全部依赖。最终随着npm/yarn统一了web和nodejs的包管理,bower慢慢退出历史舞台。

在bower处理包管理的同时,require.js则致力于理清依赖关系。require.js经过异步加载依赖(js/css)使得树状的依赖最终收敛于根节点,树上的每一个节点只须要关心本身的依赖。若是一个节点被复用,依赖子树会一块儿复用,而无需再检查依赖。最终页面所须要关心的,则仅剩依赖的根节点以及require.js自己。

编译/转译

在前端领域,编译/转译的概念首次获得关注或许该归功于coffee script和less(sass、stylus)的出现。

二者最终会被转换为js和css,而在此以前它们为语法添加了许多实用的功能,大大提升了开发效率。

除了coffee script和less以外,语法检测工具(eslint、tslint、csslint等)、代码压缩/合并工具等等也是创建在相同的技术基础之上。

现在做为后继者的babel、typescript和postcss等等已经成了前端开发中不可或缺的工具。

若是你对这一话题感兴趣,acorn.js或许是个不错的学习起点。

而以提升JS性能为目的而诞生的wasm,也是当下前端领域的热门话题之一。其产出是JS解释器所对应的字节码而非JS。

前端工程化

随着grunt、gulp等工具的出现,前端工程化在历史舞台闪亮登场。

针对不一样部署目标对代码(js、css、html)进行压缩与合并,替换指定占位符,为生成的js、css文件名添加hash,并最终输出到指定目录,等等这一系列操做已经成为了前端开发中的标准流程。

随后出现的webpack提供了更契合时代的依赖管理模式、方便的开发环境(热更新、接口代理)等等功能,并逐渐成为最主流的前端开发工具。

webpack4.x的出现,以及各类脚手架工具/项目的普及,使得配置前端工程化这一部分的工做对大多数前端开发而言变得透明。

随着http2和ES module的普及,前端打包理念是否会发生新的变化?

单页面应用

说到单页面应用,首先要提到的是history API。

单页面应用的一大基础即是由前端操控的路由行为。在history API出现以前,JS代码能够改变URL中hash的部分并监听hashchange事件,这已经使得单页面应用变得可能。而history API的出现,则使得单页面应用的路由实现有了更好的用户体验,SPA成了前端开发口中的热门话题。

其次要说的则是mv*框架。

backbone即是先驱之一。backbone将前端代码抽象为模型(Model/Collection)与视图(View)层,视图层能够操控模型,而模型经过事件(Events)与视图层交互。backbone的路由(Router)基于hash API。

纵使backbone基于jQuery、须要本身操做DOM更新、相比于MVVM和MVP模式过于笨重,却任然不能掩盖昔日辉煌与历史地位。

angular经过藏检测机制由框架层负责DOM操做与更新,使得开发者没必要先掌握原生DOM API或是jQuery的使用便能开发前端应用,将经历集中于业务逻辑、数据交互与用户交互。而angular大而全的特色则是有人喜欢有人厌。

React和vue的出现,为前端框架提供了更多选择。React引入了virtual DOM、jsx、immutable、高阶组件(HOC)、css in js、React Native等众多概念与玩法。vue则胜在易学易上手以及博览众家所长,同时提供了vuex、vue-cli、vue loader、scoped css等实用工具。

混合开发

关于前端最后一个话题是混合开发。

随着智能手机的普及,可否合并安卓与ios的开发成本成为了许多人关注的焦点之一,而混合开发如此的初衷,也注定了这条路的曲曲折折。

首先说说cordova。cordova在webview的基础上将原生与web的互通机制分装为jsbridge,并经过插件机制扩展其能力。虽然这是颇有趣的尝试,而后web自己性功能(性能、功能)上的缺陷限制了cordova应用的发展。

不过原生(或非原生)应用经过内嵌webview提供部分高可变内容,或是提供部分非核心业务页面来下降开发成本,还是APP开发中重要的一部分。

对于功能问题,一个颇有趣的尝试是native script,其经过反射机制使得JS代码能够自由调用原生功能。

而对于性能问题,react native则给出了本身的方案。React引入的virtual DOM的设计使得JS能够经过调用封装好的原生代码来建立原生界面,从而提升了渲染性能。同时React Native构建在JS/web基础上的本质,使得其保留了动态下发内容的能力。

最初被设计来挑战JS的dart语言终于在Flutter开花结果。Flutter经过Dart VM、Skia绘图引擎等来实现跨平台开发,为了提升重绘性能,其重绘算法与virtual DOM的Diff算法一模一样。

electron经过将浏览器(Chromium)、nodejs运行时一同打包的方式为web提供了开发桌面应用的能力。Atom编辑器、VSCode即是经过Eletron开发的。

PWA(渐进式WEB应用)则是经过Manifest(实现添加至主屏幕),service worker(实现离线缓存/缓存管理),Push & Notification(消息推送)来弥补web应用的一些使用缺陷,使用户得到更好的体验。

混合开发还有一个有趣的话题,是小程序。小程序具有了web应用轻快的特色(甚至更轻更快),易传播易更新,同时又提供了优于web应用的性能、功能体验。

小程序的本质是webview,在经过原生扩展webview功能的同时,小程序也对web开发中涉及内容下发的不肯定因素(例如DOM操做、eval、new Function、功能受限的Rich Text等)进行了必定限制。同时小程序用原生的页面栈管理替代了web的路由管理,提供了更友好更接近原生的页面跳转体验。

为了帮助web开发者更方便的开发不一样环境下的web/小程序应用,构建在React/Vue之上的工具,例如taro、uniapp也陆续出现,这要感谢编译/转译技术在前端领域的进一步普及。

随着w3c推出小程序(MiniAPP)白皮书,小程序做为混合应用一次成功的尝试,可否走得更远?

前端架构是什么

架构包含很是普遍的概念与内容,有许多不一样的维度。初次肩负起架构设计或许会让人感到不知从何处开始。

接下来,请容许我来聊聊,关于做为一名前端架构师,你须要负责思考的问题。

技术选型

技术选型或许是你们最熟悉也最容易开始工做的部分。

你喜欢angular、react、vue仍是其余框架?路由库、网络请求库、数据层用什么工具管理?使用或是定制化哪一套UI库?

你会使用less、sass仍是postcss?是否须要为多语言和换肤功能引入额外的工具?

你和你的小伙伴是不是ts铁粉?项目中是否须要引入wasm?兼容性预期是什么,应该如何配置babel、是否须要引入特定的polyfill?

你将面对的是一个PC网站的开发,移动web应用,或是一个electron桌面项目?响应式和自适应如何选择?若是你开发的是小程序,你会选择taro、uniapp/mpvue或是选择不使用这些工具?

你的应用是否须要与APP整合?直接使用webview仍是选择使用cordova?若是你开发的是一个跨平台APP,你将选择RN、weex仍是flutter?若是是一个web应用,是否须要经过PWA来支持离线使用?

技术选型只是第一步。请切记,咱们须要考虑的不只仅是技术自己的优劣(不少时候不一样技术自己就难以分出胜负),你还要考虑你和你的团队对于技术的熟悉程度和学习成本,并带领他们掌握你所选择的技术栈。

代码规范

你须要制定一系列规则来使团队的代码风格尽量一致,当面对大型和长期维护的项目时,这点每每比想象得重要。

你可能须要借助一些工具,例如jslint、tslint、csslint、prettier等等。你还须要考虑使用BME命名、OOCSS、scoped css、css in js仍是其余什么方法来避免CSS冲突。

固然这只是问题的一部分,还有许多问题或许没法经过工具来限制。例如,对于数组命名,使用arrlist仍是复数单词(sheep这样的单词是否会让人感到困扰?)?文件目录如何组织?点击事件是否统一以on开头?

做为架构师或是Team Leader,你须要保持按期code review的习惯来保证团队正在以好的习惯书写代码。

以及,你是否须要统一团队的工具配置,例如IDE配置、git配置(例如使用LF仍是CRLF做为换行符)、是否须要使用nrm来管理npm源并使用nvm来确保统一的node/npm版本?

UI规范

除了代码规范以外,若是有机会和设计师一块儿来制定一系列UI/UX规范,这会令你的项目长期受益。

肯定主题与配色,typography(排印)规范(包括字体、字号、行高)。

你还要与设计师一通设计一套经常使用的组件以及交互方式,以确保你的界面在设计上遵循亲密性、对比、对其、重复的规则(《写给你们看的设计书》),同时给用户带来及时、一致、可控可预期的交互体验,例如”肯定“统一使用绿色按钮,”取消“统一使用灰色按钮并在弹窗的左侧,蓝色文字表明链接与跳转,”删除“按钮使用红色而且每次点击会弹出二次确认框。

品质,来源于对细枝末节的把控。

公共代码

你须要管理你的公共代码,不管是UI组件仍是非UI功能。

即便是只考虑单独的项目,也应该将具备复用可能意义的代码放到单独的目录下管理。

为了使用公共代码库,你须要搭建私有npm仓库,仍是使用git submodule的形式?你的库是针对web仍是nodejs设计的,对于web,你将经过webpack仍是cdn的形式引入代码?若是不一样形式都须要兼容,那如下形式的代码你应当很是熟悉了:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = global || self, global.VueRouter = factory());
}(this, function () {
  //
}));
复制代码

文档

正如以前所言,你须要带领你的团队掌握新技术并高效高质量的开发项目,并提炼可复用的代码与组件,许多内容都须要文档化。

对于非UI组件,JSDoc是一个不错的文档工具。对于UI组件,storybook绝对是一个神奇,你能够经过它建立一系列可展现、可交互的组件示例,而且让其余人能够直接拷贝实例代码。

对于非来源于代码的文档,你可能须要借助静态网站生成器(static site generator)或是博客工具来书写文档,vuepress、wordpress、conflurence、石墨文档等等都是不错的选择。

为你的团队提供可参考的代码模板是个好主意,对此你可使用例如hygen(jondot/hygen)这样的工具。当我须要添加一个列表页面时,我会用模板生成初始代码,其中包含了分页加载、弹窗交互、筛选查询等等代码的模板,保证我添加的页面有一致的代码风格和交互行为。

分支管理

你须要为团队设立一套分支管理规范,若是对此你还不了解,搜索”gitflow“你能够找到须要有用的资料。

除此以外,是否全部提交到主分支的代码合并都须要提交pull request并经过code review?如何与CI/CD流程整合?commit message和提交频率是否要加以规范?merge仍是rebase?

演进能力

对于架构而言,演进能力一样重要。将webpack从3.x升级到4.x,将vue从2.x升级到3.x,或许每次升级都会成为阵痛,但咱们不能停滞不前,不然项目会慢慢变成一个难以维护的老顽固。

好在微前端理念能帮助咱们处理升级和重构所带来的麻烦。single-spa是目前最流行的微前端框架之一,qiankun(umijs/qiankun)在其之上为多项目结构提供了可行的实施方案。

经过微前端架构,咱们能够逐步替代项目中的代码,引入最近的技术,而没必要由于畏惧而停滞不前,或是每次都翻江倒海一翻。

自动化:部署 & 测试

做为架构师,你须要认真了解你所使用/搭建的脚手架和webpack,熟悉每一项配置(module、optimization、plugins...)的意义与使用。

除此以外,你须要了解git hooks、docker,懂一些shell script,以便和运维团队一块儿整合CI/CD流程。

你须要经过自动化测试以及代码覆盖率检测来保证项目稳定前进,并制定合适的适应度函数来观察项目的健康程度。可选的工具包括jest、instanbul等等,若是你须要编写e2e测试,那你可能还须要熟悉headless chrome。

若是你决定添加自动化测试,或是遵循TDD/BDD的开发理念,这很好,不过请作好准备,这但是一项会持续牵扯团队开发经历的大工程。

大前端

从更大的视野来看,你可能还须要了解许多其余的内容:

BFF(Backend for Frontend)、SSR(服务端渲染)、nodejs、graphql、grpc、消息队列(mq)、受权与认证(oauth/JTW...)、nginx、数据库(SQL、mongoDB、redis、elastic search、TiDB/cockroachDB、TSDB、graphDB...)、日志管理、docker & k8s、微服务、service mesh(istio...)、serverless...

作好准备啦吗 :)