初探Node.js:从入门到框架选择

发表时间: 2019-02-14 12:00

NodeJS是为了解决后端并发而生的,却无心插柳,成为当下前端的基石,由于当前团队的后端是python,经常不在状态,最近我想用node在后端工作替换掉。所以在这里顺便总结node的一些想法和总结。

友情提示:阅读本文大概需要 7分钟

前言

node为前端带来更多可能

这句话跟我目前的出境特别应景,企业老板不重视后端,每次项目都是后端拖后腿。node.js的存在为我的想法提供了可能。09年node.js横空出世,Node为解决后端并发而生,但却无心插柳,成为大前端的基石。伴随大前端的发展,Node也发展得越来越好,越来越重要,其应用场景从脚手架、辅助前端开发(比如SSR、PWA等)的快速开发实践,到API中间层、代理层,到专业的后端开发都有非常成熟的经验。另外,前端越来越复杂,后端服务化,今日的前端要面临更多的挑战,Node全栈给前端更多可能。

在我17年刚开始实习,node.js刚好进入Node8时代,同时这个版本也是一个LTS,除了性能提升之外,同时支持了ES6、ES7以及HTTP2(主要优点多路复用、服务端推送)。

企业级Web开发

Node基础框架除了应用最广泛的主流Web框架Koa外,Fastify也是一直劲敌,作者MatteoCollina是Node.js核心开发,Stream掌门,性能优化专家。Fastify基于Schema优化,对性能提升极其明显。最常用的三种框架如下:

Egg.js

阿里开源的企业级Node.js框架Egg发布2.0,基于Koa2.x,异步解决方案直接基于AsyncFunction。框架层优化不含Node8带来的提升外,带来30%左右的性能提升。Egg采用的是『微内核+插件+上层框架』模式,对于定制,生态,快速开发有明显提升,另外值得关注的是稳定性和安全上,也是极为出色的。

Nest

Nest是基于TypeScript和Express的企业级Web框架。很多人开玩笑说,Nest是最像Java开发方式的,确实,Nest采用TypeScript作为底层语言,TypeScript是ES6超集,对类型支持,面向对象,Decorator(类似于Java里注解Annotation)等支持。在写法上,保持Java开发者的习惯,能够吸引更多人快速上手。TypeScript支持几乎是目前所有NodeWeb框架都要做的头等大事,尤其是17年Nest算首个知名项目,在这里值得一提。

ThinkJS

ThinkJS是一款拥抱未来的Node.jsWeb框架,致力于集成项目最佳实践,规范项目让企业级团队开发变得更加简单,更加高效。秉承简洁易用的设计原则,在保持出色的性能和至简的代码同时,注重开发体验和易用性,为WEB应用开发提供强有力的支持。ThinkJS是国产老牌Web框架,在2017年10月发布v3版本,基于Koa内核,在性能和开发体验上有更好的提升。

整体来看,Node.js在企业Web开发领域日渐成熟,无论微服务,还是Api中间层都得到了非常好的落地。2017年,唯一遗憾的是Node.js在servless上表现的不太好,相关框架实践偏少。

Api中间层

前端越来越复杂,后端服务化,今日的前端要面临更多的挑战。一个典型的场景就是在服务化架构里,前端面临的最头痛的问题是异构API,前后端联调的时候,多个后端互相推诿,要么拖慢上线进度,要么让前端性能变得极其慢。进度慢找前端,性能差也找前端,但这个锅真的该前端来背么?



Node.js的Api中间层应用很好地解决了这个问题。后端不想改的时候,实在不行就前端自己做,更灵活,更能应变(就像我现在,自给自足,丰衣足食)。

• 透传接口,对于内网或者非安全接口,可以采用中间层透传。

• 聚合接口,对异构API处理非常方便,如果能够梳理model,应变更容易。

• Mock接口,通过Mock接口,提供前端开发效率,对流程优化效果极其明显。比如极客时间上公布的去哪儿开发的yapi就是专门解决这个问题的。除此之外,前端如果想做一些技术驱动的事儿,SSR(服务器端渲染)和PWA(渐进式Web应用)也是非常不错的选择。

不是Node不行,而是你不会用

这句话就是想说给那些不会node而不拒绝学习前端新技术的同学的。前几年不说,从17年至今,Node.js从8.0发展到现在的11.9。改进变化十分明显,比如:

• 比如Call back hell,现在可以通过Async函数解决。

• 比如作为过渡技术栈的thunk函数和generator,慢慢的消失在历史舞台。

• 比如Node是单进程非常脆弱,但是你真的部署对了么?

• 比如数据库事务问题,这是node的锅么?你用MongoDB玩不好,也要怪Node吗?


一般,后端开发指的是Web应用开发中和视图渲染无关的部分,但现在架构升级,Node承担了前后端分离重任之后,有了更多玩法。从带视图的传统Web应用和面向Api接口应用,到通过RPC调用封装对数据库的操作,到提供前端Api代理和网关,服务组装等,统称为后端开发,不再是以往只有和数据库打交道的部分才算后端,这样,就可以让前端工程师对开发过程可控,更好的进行调优和性能优化。



对Node.js来说,一直没有在后端取得其合理的占有率。原因很简单:

  1. 利益分配,已有实现大多是Java或者其他语言,基本是没法撼动的,重写的成本是巨大的,另外,如果用Node写了,那么那些写Java的人怎么办?(我现在想用node纯粹想替换掉本团队的python,促进团队合作效率)抢人饭碗,这是要拼命的。
  2. Node相对年轻,大家对Node的理解不够,回调和异步流程控制略麻烦,很多架构师都不愿意花时间去学习。尽管在Web应用部分处理起来非常简单高效,但在遇到问题时并不容易排查定位,对开发者水平要求略高。
  3. 开发者技能单一,很多是从前端转过来的,对数据库,架构方面知识欠缺,对系统设计也知之不多,这是很危险的,有种麻杆打狼两头害怕的感觉。
  4. Node在科普、培训、布道等方面做的并不好,国外使用的非常多,国内却很少人知道,不如某些语言做得好。


Node的优点:

• 前端实践,脚手架,工程化,快速开发;

• API Proxy中间层实践,页面即服务概念;

• 面向企业开发的Web框架;

• Node最新技术与性能调优。

Node框架

Web应用大致分2种,带视图的传统Web应用和面向API接口应用,而Node.jsWeb应用开发框架的演进时间线大致如下:

• 2010年Tj Holowaychuk写的Express。

• 2011年Derby.js开始开发,8月5日,WalmartLabs的一位成员EranHammer提交了Hapi的第一次git记录。Hapi原本是Postmile的一部分,并且最开始是基于Express构建的。后来它发展成自己自己的框架。

• 2012年1月21日,专注于Restapi的Restify发布1.0版本,同构的Meteor开始投入开发,最像Rails的Sails也开始了开发。

• 2013年Tj Holowaychuk开始玩ES6 Generator,编写co这个Generator执行器,并开始了Koa项目。2013年下半年李成银开始ThinkJS,参考Think PHP。

• 2014年4月9日,Express发布4.0,进入4.x时代持续到今天,MEAN.js开始随着MEAN架构的提出开始开发,意图大一统,另外Total.js开始起步,最像PHP里Laravel或Python里的Django或ASP.NETMVC的框架,代表着Node.js的成熟,开始从其他语言里的成熟框架借鉴。

• 2015年8月22日,下一代Web框架Koa发布1.0,可以在Node.jsv0.12下面,通过co和generator实现同步逻辑,那时候co还是基于thunkfy的,在2015年10月30日,ThinkJS发布了首个基于Es2015+特性开发的v2.0版本。

• 2016年09月,蚂蚁金服的Eggjs,在JS Conf China 2016上亮相并宣布开源。

• 2017年2月,下一代Web框架Koa发布v2.0正式版。

• 2017年10月,ThinkJS v3发布,基于Koa内核。

• 2017年12月,阿里巴巴开源Egg.jsv1,采用的是『微内核+插件+上层框架』模式。

• 2018年3月,阿里巴巴开源Egg.jsv2,全面支持async函数,性能提升30%以上。

框架的特性

Express

  • 简单、实用,路由中间件等五脏俱全
  • 最著名的Web框架

Derby.js && Meteor

  • 同构
  • 前后端都放到一起,模糊了开发便捷,看上

Sails、Total

  • 向其他语言,Ruby、PHP等
  • 借鉴业界优秀实现,也是 Node.js 成熟的一个标志

MEAN.js

  • 面向架构
  • 类似于脚手架,又期望同构,结果只是蹭了热点

Hapi和Restfy

  • 面向Api && 微服务 移动互联网时代Api的作用被放大,故而独立分
  • 类。尤其是对于微服务开发更是利器

ThinkJS

  • 面向新特性
  • 借鉴Think PHP,并慢慢走出自己的一条路,对于Async函数等新特性支持,无出其右,新版v3.0是基于Koa v2.0的作为内核的

Koa

  • 专注于异步流程改进
  • 下一代Web框架

Egg

  • 基于Koa,在开发上有极大便利
  • 企业级Web开发框架

选择:个人学习求新,企业架构求稳,无非喜好与场景而已。

Node.js本来就为了做后端而设计的,这里我们再看看利益问题。Node.js向后端延伸,必然会触动后端开发的利益。那么Proxy层的事儿,前后端矛盾的交界处,后端不想变,前端又求变,那么长此以往,API接口会变得越来越恶心。后端是愿意把Api的事儿叫前端的,对后端来说,只要你不动我的数据库和服务就可以。

但是Node.js能不能做这部分呢?答案是能的,这个是Java、PHP类似的,一般是和数据库连接到一起,处理带有业务逻辑的。目前国内大部分都是以Java、PHP等为主,所以要想吃到这部分并不容易。

对于企业Web开发来说,更重视稳定性和安全性,通过约定开发方式,提供高效开发效率。目前Egg、Thinkjs、Nest这方面是先行者,目前新项目也将打算采用此类框架。

好消息:Flutter给予前端新活力

// 先看一段flutter代码感受一下class ToolbarDemo extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( actions: <Widget>[ new IconButton( icon: new Icon(Icons.star), onPressed: _handleClickFavorite ), new IconButton( icon: new Icon(Icons.add), onPressed: _handleClickAdd ) ], ), body: new MovieDetailScreen(), ); } _handleClickFavorite() {} _ha// 将菜单项添加为App Bar的Actions。这就是全部不需要再将图标导入成XML文件,不再需要重写回调。并且只需要Widget上加一些小的Widgets就可以了。

Flutter的诞生,最大的优点不是给予前端JS开发者创造原生APP的机会,而是直接解决了兼容性问题(PS今天最大的新闻就是苹果撤销了FB的IOS企业开发者证书),作为前端我将不再纠结于weex或者RN,而是直接使用flutter写重构原项目。

参考书籍

Flutter中文网

最后

今天的分享就到这里,有问题欢迎大家留言,谢谢~