我第一次听说nodejs技术大概是在2009年年末,不过我真正认真在网络上进一步了解nodejs还是在2010年年中,当时对nodejs的认识和我现在对nodejs的认识有着天壤的区别,开始想了解nodejs我只是为了感慨谷歌公司开发的V8引擎居然如此强大,它不仅仅可以作为chrome浏览器的javascript内核运行平台,居然还能为服务端使用javascript语言作为平台,通过对nodejs的了解让我认识到chrome浏览器是如此的优秀,但是如此相对的是我并不认为javascript作为服务端语言真的会有市场。

为什么我当时会认为javascript作为服务端语言的前景堪忧呢?我当时有如下的思考,这些思考放到时下nodejs已经非常火爆的背景下,我相信对很多朋友任然有参考意义,下面是我当时的思考,具体如下:

质疑nodejs思考一:2010年之前我还不是敢自称自己是一名专业web前端的工程师,因此对于javascript的认识和掌握程度也不能和现在相比,但是对于javascript的难学,难深入却是有着切肤之痛,因此我想javascript作为服务端语言就是让会其他服务端语言的工程师更加深入的学习常被服务端工程师诟病的javascript,这么做的结果无异于逼迫服务端工程师转向成web前端工程师嘛,这个想想就让人觉得不现实。

质疑nodejs思考二:我对web应用开发的技术选型认识比较肤浅。技术的选型是个很宽泛的问题,回到我对nodejs的质疑思考主要是体现在web应用服务端语言选择上,在中国用作web服务端开发的语言非常多,但是主流的无非就是java、php、C#以及C语言系列,当然web服务端技术发展到现在Python、ruby也是有一定市场,作为一名具体干活的软件工程师对于项目选择何种技术是没啥发言权的,因此我常常觉得技术选型就是项目经理或者是技术经理以及架构师的问题,而大多时候我们去询问为什么用这个服务端语言得到的答案都是非技术性的回答,例如:公司主要是使用php啊,java比较流行人好找啊,C#开发快啊能很快的完成工作,很少有人会这么告诉你我们的项目是个什么样的项目,这个项目使用A语言比使用其他的B语言、X语言有何种好处和优势,其实中国很多软件企业做项目在技术选型这块都很粗,说的难听点其实就是很多能控制项目的人技术水平很难被恭维,当然大部分项目其实使用什么技术实现并不是太重要的问题,但是这个到了技术架构异常复杂的大型网站技术选型问题就显得尤为重要,这个认识主要是来自于我阅读《淘宝技术这十年》所感受到的,淘宝网站的技术选型随着业务的发展变化的如此之大,颠覆性如此之高,这个在我待过的很多项目组都是难以令人想象的。

Web应用发展这么多年,那些占据了天时、地利和人和的现有技术基本都是处于一个垄断的地位,新的同类型语言想突破重围必然有着自己独有的技术优势,这就好比在中国做互联网如果有家新型互联网公司可以突破BAT的围追堵截,那么这家公司一定是有着自己得天独厚的优势,所以nodejs一定是获得一种得天独厚的优势,那么nodejs优势在哪里了?不过在讲述nodejs的优势之前我们先来讲讲上篇文章里遗留下来的问题。

其实上篇里我讲到前端MVC,文章里只是着重讲到了V层即视图层和M层即模型层的问题,而唯独没有专门讲解C层即控制层的问题。在前后端分离文章第一篇里,我谈到如果把MVC框架里的C层以作为连接web前端和web服务端的角度来理解,C层主要承担了三个方面的工作,它们分别是:路由、报文格式转化和页面渲染的工作。前端MVC在处理报文格式转化和页面渲染这两个方面还是比较容易做到,但是在做路由这块存在一定问题,前端MVC框架对于获取服务端数据这块以及异步请求处理方面其实和传统MVC框架的处理的手段本质上是类似,只是实现载体有所不同而已,但是控制层还有一个路由功能,其中用于页面切换的路由存在一定的问题,不过这个切换也要限定一下范围,页面通过ajax技术让页面部分刷新,假如这种部分刷新让页面展示效果发生很大变化,对于用户而言也是页面发生了切换,但是这种切换是不会让地址栏的url产生任何改变,这就是问题的根本所在了,我在上篇里已经讨论过这些问题,通过这些问题我们发现如果页面转化时候地址栏的地址随之也发生改变是会给用户体验、网站的友好度以及SEO优化带来好处的,如是乎我提供了一种手段,那就是使用锚链接来帮助我们实现url的变化,因为锚链接只是作用于浏览器,因此这种手段是对前端MVC的C层实现页面路由功能的一种很好的支持,但是因为这种方式需要在javascript里完成,那么对于SEO优化就产生了问题,最后我提出了页面切换我们最好使用同步请求的方式。

这个时候问题来了,如果要使用同步请求,那么这个同步操作自然是要让服务端来控制,这么做的结果就是让服务端再去回收部分控制层的功能,这样下来一个使用前端MVC架构的网站就有点不太纯粹了,具体点就不是一个单页面的网站,这里我们的讨论又回归到了单页面的问题了,前文讲前端MVC框架很多热心网友对我的论述发表了有价值的评论,但是我发现我的想法有些朋友可能没有真正理解(这也许是我的表述的问题吧),我前端MVC讲述的一个思路是以批判前端MVC的角度进行的,我早些时候和一些网友探讨过前端MVC的设计问题,有些朋友在没有做具体web前端MVC架构前总是想实现纯粹的前端MVC框架,延着这些朋友的思路我们就会把所有的C层和M层的东西都移到web前端,我常想如果真的这么实现了,结果自然就是单页面网站了,或者就是在前端引入了复杂的模型层设计,不过探讨毕竟是探讨真的实现时候很多朋友就会知道了难度所在了,所以说理想和现实是有差距的,这话又一次灵验了。

这种理想和现实的差距,其实就告诉我们一定有个地方出问题了,那么问题在哪里了?下面我将我对这个问题的思考,总结如下:

问题思考一:让前端承担大部分MVC的工作,那么前端本身的技术能力是否能达到所有的要求吗?这个回答似乎是肯定的,例如单页面的出现就代表了这种可能性,javascript也是拥有强大的面向对象的编程能力,因此再写复杂的业务模型层也是没问题,但是前端这么做了以后其实并不能满足所有人的需求,例如:SEO的要求,SEO很多技术都是以同步网站请求技术为根基,这个和前端MVC框架以ajax技术为根基产生了冲突,这就让前端技术产生了局限性。使用javascript面向对象技术来实现业务模型,这个也是有问题,javascript的面向对象的学习成本和精通难度超出了传统的面向对象的语言例如像java这样的语言,而且javascript要设计和写出更加容易维护的代码是非常不容易的,这么做不符合我在存储系列里讲到的要用最简单的方式实现的原则,这其实也是说明前端技术能力不足的问题。

问题思考二:其实不管什么形式的前后端分离方案它最根本的思想就是让前后端进行解耦,让不同技术语言体系下的人能做到工作的隔离,最后协同起来各自发挥出自己的最大价值,但是如果我们只是按前端,后端的角度来做分离,是不是有点粒度过粗,考虑是不是过于片面了?特别是这个片面的问题,web应用的问题并不是一个纯技术问题,而是一个技术和业务结合的问题,因此任何应用于生产的技术方案都会受到业务的影响,例如上面当我们要考虑SEO的问题,考虑开发难度的问题,那么纯粹的前端MVC的框架就会显示出自己的局限性。前端技术无法改变浏览器地址栏的url,这个从很多角度思考是个合理的设计,但是到了前端MVC里对C层的设计而言则变成了一种技术手段的局限性了。因为这种局限性就让我们不得不回到问题的原点状态,例如页面的同步请求,而同步请求最合理的控制地点就是服务端了。

问题思考三:本思考是一个延生性的思考,我从事这么多年的web开发,我其实一直困惑于web应用开发和MVC的关系,为什么我们做web应用开发时候都要那么强调和重视MVC设计思想呢?难道web应用开发的世界没有MVC就不能活了吗?回首下web应用发展的历史,在web应用开发的忙慌年代,的确是看不到MVC的影子,那个时代的确很自由,自由到许多web应用混乱不堪,质量和健壮性差的不能再差了,这个时候一个英雄出现了那就是MVC,MVC代表了一种次序,一种基本的法则,这就好比人类社会建立的根本原则一样,这些原则让人类和野兽有了区别,人类也因为这些原则而成为万物之灵长,相比之下MVC就是web开发世界里的游戏规则和行为准则,因此只有当我们从MVC角度思考web应用的建设,才会让web应用更加的优秀,这也就是在讲述前后端分离技术时候我都是以MVC思想作为准则进行思考的。思考回到具体的场景,MVC思想的运用就是让我们把web应用开发里可以归为一类的场景聚集在一个范畴之下,不同范畴使用一种双发都可以接受的统一准则进行沟通,这么一来我们就把需要解决的问题简单化了,各个独立的范畴因为减少许多不必要的干扰,因此能让它们发挥出更大的潜力,更重要的MVC还让web应用伸缩性,健壮性,可维护性大大增强。例如在很多传统web应用开发里在控制层这块前后端的矛盾就是属于MVC规则使用不完善所致。

单页面的应用存在很多问题,因此需要同步请求的介入,这就导致了服务端再度回收了失去的控制层的功能,这么做也无可厚非,但是我很担心这个改进的引入会不会导致传统MVC框架里控制层的混乱问题,根据我的经验,这种混乱的程度已经降低了很多很多,基本我们可以忽视原来C层的问题了。

不过很多有追求的web前端工程师对于这种不纯粹的前端MVC的异议还是很多的,大部分异议还是源自浏览器能力的局限性,当服务端很多方面被弱化后,也许可以解决我们以前在前端被服务端束缚的很多问题,但是同时又产生了新的问题,这些新问题我总结如下:

新问题一:在传统的网站动静划分里,我们常把浏览器端的技术html、css和javascript归结于静态技术的范畴,如果网站使用Web前端MVC那么前端就会接过很多动态网站的功能,这个时候传统的静态技术就被人为的演变为动态技术。回顾网站的发展历程,基本是从静态到动态的转变,这个结论用在时下其实已经有点不太对了,随着网站越来越庞大越来越复杂,网站技术发展逐渐开始逆向进行了,网站从动态化向静态化转变的需求变得越来越强烈了,这也是时下前沿的前端技术正在解决的问题,例如本系列的主题网站静态化技术就是顺应这个发展趋势而来的,所以前端MVC框架在这点上有点逆历史潮流的问题了。

新问题二:前端MVC让web前端的技术难度和架构难度成指数级上升,而javascript语言天生有着自己设计的缺陷,这个缺陷在写大规模复杂应用时候就显得尤为突出,例如:javascript没有模块化管理,javascript面向对象的实现难度,所以前端MVC的应用可能会变相的提升企业的技术成本和开发成本,当然很多新的技术手段能解决javascript固有的缺陷,对这些新技术有个更大的问题就是“你会吗“,不会的话首先要解决会的问题,这也是个成本问题。

新问题三:当前端真的越来越独立于服务端后,这会导致服务端一些可以优化web前端的重要技术就很难实现了,例如网站静态化系列里讲到了缓存运用,CDN的运用就很难达到预期效果,或者根本没法使用,因为这些技术的根基都是认为网站动态性是由服务端发生的,而客户端霸占了动态性,那么这些技术的作用就被限制住了。

由此我可以下个结论:如果前后端分离方案是以浏览器和服务器角度来划分并不是最好的前端分离方案,那么前后端分离方案还有没有新的解决思路了?这个真的有,那就是nodejs参入的前后端分离方案。

其实前后端分离的驱动永远都是前端强于服务端,而前后端分离的重要目的也是要给web前端创造一个更加干净的开发环境,那么写的代码是否是在浏览器上跑还是在服务端上跑这个并不是太重要,所以引入nodejs,就是让服务端也能跑javascript代码并不会是让人无法接受的事情,回到前后端分离方案里以服务端驱动的前后端分离方案,我曾说过这个方案能获得服务端开发人员更多的掌声,我相信这个掌声不会是服务端为前端的喝彩,而是服务端终于从web前端解脱出来了,这样服务端运用更加高级的SOA技术就成为了可能,那么我们把web前端的控制层使用nodejs替代,这么一来我们既可以继承所有传统MVC框架的优点,同时也达到以前后端分离的根本的问题就是为web前端创造一个很干净的开发环境问题,那么我们在前端MVC框架使用时候遇到的问题都会很好的被解决。

Nodejs的运用让动态网站的动态性再度停留在了服务端,那么我前面讲的那么多网站静态化技术就可以和前后端分离方案很好的融合了,因此本篇先不具体讨论nodejs做前后端分离的实现手段了,在下篇讲从网站静态化角度重新审视前后端分离方案时候一起讲解,这么做会更加符合本系列的主题。

现在我们可以解答为什么nodejs技术可以突破传统服务端技术的包围,因为nodejs可以让前后端达到更高程度的分离,从而让前后端各自发挥自己的优势,很有意思的是,虽然nodejs技术属于服务端范畴,但是它却是前端工程师驱动来普及的,这绝对是web前端逆袭啊。