2017年的前端将会消沉还是暴走?

2016年前端领域爆发出一堆新的东西,webpack横行霸道,react风靡一时,typescript也占尽风头。有兴趣对2016年前端领域的新事物一盘了解的,可以读下这篇翻译的文章,采用对话形式,让人抓狂,最后还不忘黑一下Python3。

这篇文章,主要想讲一下我对前端发展的一点想法,以及对2017年甚至未来的一些预测。

上图是我总结的自己对前端整个发展的思考。首先,它并不是代表所有阶段,而是各个阶段的杂糅,形成现在的这个局面。其次,它更多的是站在程序员的角度重新去看到自己走过的成长道路。

前端开发工作模式的不同阶段

一谈到前端的发展,总会把前端产品或技术构成的历史总结一番。但是再怎么发展,最重要的因素是人,所以更应该站在开发者的角度去谈谈作为一个开发者,都经历了哪些工作模式。

“三剑客”的远去

早期的前端,更多的是以html文档的形式呈现出来,这和我们学习前端技术的顺序是一样的,它们是前端开发的核心基础知识(core basic knowledge),掌握它们没什么用,但是不掌握则无法理解前端工作的实践认知。这个时候的工作模式大抵是写好html的架子,然后用css处理好界面,用Javascript作零星的点缀,让页面动起来。

风靡一时的jquery

2006年jquery就发布了第一个版本,但是真正风靡世界是在2009年左右,从此以后,它甚至成为进入前端领域的初学者先学习的东西。甚至可以说,初学者使用jquery,可以直接跳过对Javascript中dom操作的一些学习。jquery先进的地方在于将纷繁复杂的操作封装为接口,这种设计甚至影响了后来各类库的开发。就连现在ES标准,也试图将原来的一些全局函数重新封装,提供为对象接口。

jquery、react等前端库让前端开发者解放了自己重复撰写某些功能模块或函数的时间,用更简单的方式实现快速开发。比如jquery中对ajax的封装,几乎成为后来前端开发的一种标配写法。虽然到了2016年,还会有新的库成为热点,比如reactjs,这个2016年最火的库,解决了视图层面的性能问题。工作模式上的改变并没有太大变化,类库的使用主要是缩短开发时间提高效率。

前端开发框架

当随着前端应用越来越复杂,代码之间的逻辑关系越来越紧密,耦合度越来越高时,普通的面向过程的编程已经无法满足我们对应用业务的需求。前端编程框架也出现在视野中,其中最知名的莫过于angular,采用MVC模式,将前端代码合理区分,不同的代码群实现不同的逻辑,比如Model指处理数据相关逻辑的代码群,而View指处理界面显示的代码群。

框架里面也可以使用库,但是不同的框架,蕴含的思想不一样,一旦确定了使用什么框架,后期产品代码库庞大之后,基本不能改变使用的框架,所以最好选择靠谱的长期支持的框架来使用。

除了angular,还有backbone、ember等,2016年最火的,莫过于angular2和vue.js了。前端开发框架让前端开发不仅拥有明确的业务区分,而且让代码管理成为可能,一个产品的开发可以分为不同的模块来进行开发,不同的开发者专注于不同的业务层面,工程化成为可能。这种进步标识着前端开发不再依靠后端来决定开发模式,而是可以自己来决定在客户端如何处理,后端更多的专注于数据处理。

工作模式已明显于前一个时代不同,特别是SPA(单页应用)的出现,使得原本提倡的应该将html,css和Javascript分开的这种思想破碎了,前端框架的使用,使得这三者重新杂糅在一起,只不过以前是全部杂糅在html里面,现在是杂糅在Javascript里面。由于这种变化,以前可以一个人专注写html一个人写样式一个人写脚本这种模式完全不可用,现在的模式必须是由一个人(团队)来完成三个方面的工作。看上去把问题搞复杂了,但是实际上这使得应用的表现形式更加丰富,框架的使用使得大规模的代码管理成为可能,大型前端应用出现,性能也提升很多。

模块化

node出现时,遵守commonjs模块化规范,凭借require和module.exports这两个特殊语法,实现了node模块的复杂体系。在此基础上,npm大行其道,package成为模块的集大成者,npm给模块发布安装提供了最好的实践。也因为npm的盛行,基于此的webpack打包工具成为2016年最火的工具之一。

2015年发布的ES6标准更是将模块标准化,成为Javascript标准的一部分。但是标准并没有吸收commonjs的成果,而是直接跳过包括amd在内的一些现有规范,直接构建起自己模块化规则,采用export和import进行模块之间的导入导出。这也就是说未来node可能同时支持commonjs和ES6的模块规则,毕竟以前采用require实现的各种程序不可能全部改变自己的代码来适应新的模块化规则。不过现在babel在做这件事,支持ES6语法,或者把ES6代码转换为ES5/commonjs来执行。

当模块化成为主流的时候,模块化编程就逐渐成为前端开发的主要工作模式。这种转变直接导致前端工作模式的一次变迁,从传统的手工编程到自动化构建。

构建(build)已经成为前端代码的标配。构建,是一个将source源码经过编译、打包、压缩、发布等操作按照开发者的意义自动化完成的过程。也就是说,开发者不再像以前一样,写出直接用于运行于浏览器的前端脚本,而是要经过构建工具进行构建后才进行发布。构建工具既可以是现成的,也可以是自己编写的,在源码里面,你不必严格遵循原始的Javascript写作语法和规则,当然为了向后兼容,遵循标准的ES语法和规则更好,但是现在的浏览器并不完全支持ES6,因此,需要将写出来的ES6转换为ES5代码,源码中使用到模块化的,也要通过打包工具,使其在浏览器中可用,这就交给构建工具来完成吧。grunt、gulp及其插件体系,可以帮助我们完成自己的构建工具。

npm、gulp、webpack这些原本和前端两个次元的工具,也成为前端开发者必须了解和掌握的,因为,前端开发的工作模式已经进入构建时代。对于一名开发者而言,单纯掌握core basic knowledge和library以及一些前端开发技巧,已经无法完成前端开发工作的需要了。不掌握这些和构建相关的工具,甚至自己编写(修改)构建工具,已经无法称自己是一个合格的前端开发者了。

component的时代

模块这个概念在前端领域的横行,使得代码重用率有了巨大提高,但是也带来了一些问题,比如管理繁杂。然而模块,更多的是注重功能,然而,真正要达到application这一层,还需要将这些功能组合起来,才能组合成真正的应用。然而这种功能组合,会使得编程又回到了复杂的体系,原本模块是为了解决相互之间的高耦合问题,但框架式的开发使得依赖太过紧密。在package和framework之间阈值太大,导致用package撰写出最终的产品体系非常复杂。构建工具也无法解决这个问题,它的问题本质是粒度问题。module和package粒度太小,framework和application粒度太大,两者之间是否存在一种过渡状态的颗粒呢?

组件,这种粒度适中的形态,让开发者可以尝试使用各种包完成一个业务模块,这些组件经过调用可以独立运行,也可以塞进framework成为产品的一部分。这让开发者可以专注于用package实现应用的一部分,而不用太过考虑全面,从而解放功能实现的专注度。另一个好处是,这种形态让重用更加高度,在使用package开发组件的时候,并不会直接将package打包进组件,而是在后期使用或运行的时候使用npm install来安装这些包,这使得package部分的重用最大化,而且对于framework这一层而言,也是重用package和component,不同的产品,使用不同的component就可以封装出来,即使它们底层的package可能都差不多。component的表现形式也可以多种多样,不过目前组要是以package的形式发布,所以实际上component本身使用了package,同时自己也是package,它们之间是引用关系,而不是包含关系,这就让代码更加合理。构建在前端的地位,是使得符合ES标准的代码在未来更换构建工具的时候,还可以用,你写的是符合ES标准的代码,所以,未来无论前端发生多大的变化,这些代码都可以工作,你只需要调整构建过程即可。

早期前端开发,必须将全部业务代码放在一起测试、运行、开发,开发者不得不对全盘逻辑进行了解。但是后来模块化开发成熟后,开发模块的开发者只需要根据功能需求,撰写符合需求接口的模块即可。但模块仍然是面向功能的,当面向业务的组件开发成熟之后,开发者可以完全脱离全局业务逻辑,而是专注当前的业务逻辑进行开发,从交互到后端api,都可以独立在这个范围内实现。这就将前端开发剥离为component和framework两个大的层面的开发。

Web Components也在2016年初显端倪,它将成为下一代web开发的标准之一,也就是说未来web开发中将统一组件的接口标准,组件的实现不同,但对于使用组件的开发者而言,接口相同。例如在自己的网站中使用了来自Google的组件,使用的时候按照web标准进行调用。但是有一天对组件样式不满意,于是自己重新写了组件。再次使用时,不需要修改调用部分的代码,组件内容的改变并不影响其接口。

前端开发的工作模式并没有太大的变化,构建是不可避免的。但是对于开发者而言,更加专注所在领域的业务上,前端开发者个人能力的提升和对业务的熟悉更加重要,不同行业领域的开发者之间,有着越来越大的差别。这也是我想说的另一个话题,叫professional focus。

前端开发的方向

随着前端体系越来越庞大,不同领域也开始从原来的浏览器端前端开发中剥离开来。比如在桌面应用中采用web技术,在手机应用中采用复合开发,在服务端使用node提供服务等等。

嵌入web的应用

以前我们称为网站,现在都全部改称为web应用,网站只是web应用的一种形式,web可以应用到更多的开发中,比如浏览器内部,比如编辑器内部,比如一些桌面客户端内部。采用web的形式嵌入到应用中可以让应用轻量化,而且同时更新更加可控,以往一个bug需要升级应用才可以,现在只需要在server端推送最新的代码即可修复。

native的暴走

native开发已经是前端的重要领域了,没有一个前端开发者不需要关注这个领域。特别是react native的推出,使得前端开发已经完全具备开发本地应用的能力。基于这种思想,用Javascript开发应用程序也顺理成章,例如编写编辑器的插件,浏览器的应用,中间件。基于node写一个本地应用进行文件处理也非常简单。微信小程序也于年底推出。这类应用和html5应用不同,html5应用试图一个应用适用不同平台,native则只是利用这么编程语言的特性进行编程,最终的应用仅适合基于的平台。

方兴未艾的server端

node的出现使Javascript出现了无限可能。因为作为服务器的node,提供了直接操作文件系统的接口,使js操作文件和其他进程成为可能。这也是上面实现本地应用的原因之一。server端的开发依赖于node,通过node提供的接口,可以对文件进行读写,提供本地service,甚至对其他应用程序进行操作。作为经典的service,利用express或koajs可以像任何其他的开发语言一样,提供服务端的web开发框架。这使得前后端的语言都是Javascript,让前端开发者一站式解决所有问题,可以说是近几年年最令人兴奋的事。

交互向

回归web前端开发,未来几年,前端开发者之前的区分会越来越严重,也就是说越来越多的开发者会在两种不同的业务类型中开发,一种是围绕数据流为中心的application,另一种是围绕视觉流为中心的产品。而这种围绕视觉流为中心的产品开发,就是交互向前端的主要阵地。最明显例子就是游戏领域,这是众所周知的红海,也是技术门槛。前端开发者要进入游戏领域,除了要掌握基本的游戏开发库,还要有实践经验,有创意,能够发挥创造力。除了游戏,各种莫名其妙的为营销活动服务的专题页(或者跟游戏相结合),包括未来的3d应用,都是前端在交互向的重头戏。

数据向

传统的web应用其实就是以数据流为中心的,例如网站、社交平台,但是未来这种倾向可能更加严重,那种业务流程相关的数据向开发可能谁都能搞定,但是能够将大数据处理后可视化展示出来的能力不是谁都具备。d3这个库的出现为可视化提供了捷径。但不仅限于此,比如table和grid,这两个看上去差不多的东西,本质里面到底有什么区别?本质的区别是grid是画出来的。前端已经完全沦陷为通过api获取数据进行展示的开发模式,不可能再回到以前通过server端渲染数据的时代了。既然如此,只会在可视化这条路上越走越深。我想,这也是这个时代回归大道至简的需求。

结语

在知乎上看到有人提问“2017年学前端应该怎么学”类似的问题。我觉得2017年已经不再是单纯把前端看作一个事物的时代了,就像Java一样,你会问“安卓开发”,前端也一样,你应该问“前端数据可视化”或者“前端游戏开发”这样比较具体的领域。一旦把范围缩小,具体应该怎么学,怎么去积累经验,就变得非常明确。开发者应该明确自己的兴趣在哪一个方面,并且深专进去。

扩展阅读:

  1. Web 开发模式演变历史和趋势
  2. 2016 年移动 Web 的发展,2017 年的前端又会怎样?
  3. 前端包管理器争端,只不过是构建工具的牙缝菜
  4. Morningstar的产品开发模式

2017-01-29

已有1条评论
  1. lsql 2017-06-10 13:04

    作者的见解很独到,眼光放的很远,现在的前端几乎已经湿透到方方面面了,目前也正在考虑学习react native