node.js上除了Express还有哪些好用的web开发框架

老司机都有体会, 开发本身没有多难, 最纠结其实是最初的技术和框架选型, 本没有绝对的好坏之分, 可一旦选择了不适合于自己业务场景的框架, 将来木已成舟后开发和维护成本都很高, 等发现不合适的时候更换的成本更是令人胆颤, 数据观最早的接入层是采用ThinkPHP开发, 后来基于种种权衡后决定用node.js重制, web开发框架选型就成为首要必须慎重解决的问题, Express当然是头号映入视野的名字, 本着全面考察重点择优的原则又花不少时间简单研究对比几个主流的node.js web开发框架, 真的有乱花渐欲迷人眼的感觉, 把当初列入备选的几个框架简单评论一下:

  ?Express 
  这个就无需再介绍了吧, 几乎已经成为闭眼推荐的首位, 有点在于简单灵活, 缺陷也在于过于简单, 相当于每个功能都需要自己选择不同组件搭建, 虽然有各自脚手架帮助, 但对于开发大一点的系统还是缺乏必要的代码框架, 光搭建整合基础框架就会花不少时间, 对于新上手node.js不久的笔者而言,自由灵活也意味着容易犯错, 最好有类似Djongo/ThinkPHP那样out-of-box即开即用的开发框架快速上手而不是坐而论道.
  优点: 插件众多, 简单, 自由, 丰俭由人, 适合于简单业务逻辑模型 
  缺点: 缺少规范性, 需要自己选择搭配的组件太多, 不太适合应用复杂的业务.

  ? Koa 
  Express基于ES6的升级版, async/await解决ES5 callback hell的痼疾, 但是选择框架不仅仅是框架本身, 同时还要看插件扩展的丰富和成熟度, 因为没有用过担心后面遇坑填不平而放弃, 做研究可以大胆, 做产品必须谨慎.
  优点: ES6语法, 逻辑易懂 
  缺点: 刚开始应用不久, 担心有扩展不足和不兼容问题

  ?Meteor 
  一个完全统一前后台开发的一站式框架, 从后台数据库到前端view全部包含在内, 特别适合于重度依赖websocket的SPA(单页面应用)开发, 国外流行的Asana就是完全采用Meteor框架开发.
  优点:一站式解决方案, 前后台一体开发, 强大的websocket+ mongoDB支持 
  缺点:自由度不够, 和传统的Web框架概念差异较大.

  ?socketstream 
  如果说RESTful是Ajax的概念基础, socketstream实际上更接近于早期RPC的思路, 将函数调用(functionname + parameters)建构在websocket协议层之上, 例如下面这段代码其实就是调用远程函数计算.

  //--server side in /server/rpc/app.js 
  exports.actions= function(req, res, ss){ 
  //return list of actions which can be called publicly 
  return{ 
  square:function(number){ 
  res(number* number); 
  } 
  } 
  } 
  //--client request 
  ss.rpc(‘app.square‘,25)

  优点: 完全web socket, 函数+参数==>返回值概念简单 
  缺点:和主流的RESTful概念偏离较大, 很少看到实际应用案例

  ?Sails.js 
  这是本文的主角,相当于针对典型应用框架所需组件在Express基础上的集成封装,把日常开发常用的功能都给你集成好了, 开箱即用, 完全兼容Express的middleware, 如果了解ThinkPHP就更容易上手了, RoR / Convention overConfiguration的概念可以立即进入实际业务开发, 反正做什么事情应该怎么做人家都给你规定好了, 可以从实验代码逐步迭代到中大项目的生产代码.
  除了传统的HTTPRESTful外还同时支持websocket - 同一个请求协议既可以通过Ajax发送, 也可以通过websocket发送, 这一点让人赞赏.
  优点: 开箱即用的全功能Express增强框架, 内置支持websocket 
  缺点:(据说)ORM性能不好

  Sails.js框架组成介绍

  既然是一个全功能的MVC框架, 那么开发一个应用所需的常用组件自然包含在内除非你有特殊要求, 这一点非常类似ThinkPHP, 从目录分布上介绍一个概貌先:

  ? api/ 
  Model /Controller都在这个目录下, 所有代码根据不同职责都被定义好位置, 这一点非常有利于大型项目开发的代码规划.

  ?api/controllers 
  这里面写的每一个controller + function 都会被自动映射到路由上, 充分体现convention over configuration的特点, 与ThinkPHP如出一辙, 来一个最基础的hello world吧 -api/controllers/TestController.hello() 方法被自动映射到/test/hello 而无需任何配置.

  //api/controllers/TestController.js 
  module.exports= { 
  hello:function (req, res) { 
  returnres.ok("Hello World"); 
  }, 
  controller下可以随意进行目录分层, 每增加一级目录就相当增加一级路由.
  api/controllers/user/TestController.hello()==> /user/test/hello

  ?api/services 
  项目大了程序就必须进行职能分层, 业务相关都作为独立的service一层放在这个目录下, controller仅负责request / response及差错处理, 既简化controller的代码逻辑,又可以让service代码被不同模块复用。作用相当于一套全局函数库。
  常见错误:service代码不要直接通过res做应答, 那本来是属于controller的职责.

  ?api/policies 
  作为前后台分离必然要提供Ajax API给前端, 那么访问鉴权和安全控制必不可少, Sails.js在Express middleware基础上封装为policy实现访问控制, 如果说上面那个 /test/hello 仅允许登录用户才能访问, 那么加一个验证session的policy就是.

  langset是检测多语言设置的policy, sessionAuth仅允许带有登录session的API请求通过, 多个policy可以组成一个检查链, 只有全通过了才能达到最终的controller, 中间任何一个policy都可以直接response拒绝服务.

  config/policies的鉴权配置
  module.exports.policies= { 
  ‘*‘:true, 
  TestController:{ 
  ‘*‘ :‘langset‘, 
  ‘hello‘: [‘langset‘, ‘sessionAuth‘], 
  }, 
  api/policies/sessionAuth.js实现

  如果是页面请求则redirect, 如果是ajax则应答403forbidden. 
  这里还借用了passport的req.isAuthenticated(), 根据业务需要可以结合多种检查方式, 把每个独立检查点都作为一个policy, 然后配置为一个policy chain, 功能独立又可以灵活搭配, 类似应用登录检查中的异地登录, 长时间未登录, 连续密码错误, 动态验证码校验都可以用policy的思路去实现.

  module.exports= function (req, res, next) { 
  // Useris allowed, proceed to the next policy, 
  // orif this is the last policy, the controller 
  if(req.isAuthenticated()) { 
  returnnext(); 
  }

  // Useris not allowed 
  //(default res.forbidden() behavior can be overridden in `config/403.js`) 
  if(req.wantsJSON) { 
  returnres.forbidden(‘You are not permitted to perform this action.‘); 
  } 
  returnres.redirect("/login"); 
  }; 

  ?api/responses 
  常用的response页面都在这里了, 当然可以增加新的, 调用就是res.{response_name}(message)
  *badRequest.js - 400 
  *created.js - 201 
  *forbidden.js - 403 
  *notFound.js - 404 
  * ok.js- 200 
  *serverError.js - 500 
  Oops,404了

  ?api/models 
  Sails.js的ORM实现, 这个目录下的class都会映射为一个持久化的object及attributes, 采用Waterline hook机制实现, 可以配置为MySQL/MongoDB/Oracle/PostgreSQL多种常见数据库.

  考虑到node.js更多作为中间转接层角色出现,真正ORM与核心业务逻辑还是交由Java等后台实现为妥,所以个人并不建议过多采用Sails.js自身的ORM,聊胜于无吧。

  ?assets/ 
  images/fonts/js/css/模板等静态文件下载根路径,build时可采用Grunt进行打包丑化等操作。

  ?config/
  osession.js - 配置session可采用的存储模式,redis/mongo等多种存储方式可简单配置支持。
  ohttp.js - default按照缺省配置就够用了,如果还想自己微调可以完全配置Express的middleware次序。笔者在middleware里面增加了一个客制化的 response-time 中间件用于记录每个API请求的log。
  olog.js - 配置log输出appender,CAUTION:输出log一定要用sails.log而不是console.log,因为可以根据需要配置log输出方式而不修改代码,笔者采用了sails-hook-winston+winston-daily-rotate-file实现按日期命名log文件。
  oroutes.js/policies.js - 路由和安全策略配置双剑合璧,简单而强大。
  oviews.js - 配置View模板库。

  ?views/ 
  如果是正式项目个人更建议用handlebars替换缺省的ejs模板库,优雅替代模板里面的js代码逻辑,尤其可以自定义helper函数瞬间让开发者不必再依赖模板库提供的有限逻辑处理,充分发挥函数式语言的优势。

  这是原生ejs模板实现的403:

  <% if (typeof data!== ‘undefined‘) { %> 
  <%= data %> 
  <% } else { %> 
  You don‘t have permission to see the page you‘retrying to reach. 
  <% } %> 
  

  这是handlebars实现的403
  <divclass="content"> 
  {{#ifdata }} 
  {{data}} 
  {{else}} 
  您没有权限查看您要访问的网页。 
  {{/if}} 
  </div>

  Sails.js框架常用搭配的七种武器
  框架自身所能提供的功能毕竟是有限的,扩展库才是一个框架丰满与否的关键,此处结合笔者的实践推荐几个可用的框架扩展。

  1. 长生剑-async.js + lodash.js 
  这是两个被内置的核心js库,前者用于流程控制,后者用于数据结构处理,即使不用sails.js也应该深入掌握。

  2. 碧玉刀-handlebars 
  放弃ejs吧,handlebars更优雅简洁,而且具有更强更容易的处理逻辑扩展能力。全部秘密就在于注册一个自己的函数。
  这是一个实现编码转义的helper函数
  Handlebars.registerHelper(‘unescape‘,function (v) { 
  returnunescape(v); 
  });

  3. 离别钩-winston 
  写后台不充分考虑log记录简直等于不带手机去旅行,sails-hook-winston可以无缝将sails.log转接到任意winston transport插件上而无需修改任何代码。
  console/ winston-daily-rotate-file / http / LogstashRedis 是实际使用中的transport。

  4. 霸王枪-passport 
  基于passport的第三方认证已经成为JS的标准,几百个知名strategy即插即用,几行配置代码就可以实现微信/微博/钉钉/QQ第三方登录认证,当然最好对OAuth2有简单了解。

  5. 多情环-socket.io 
  Sails.js缺省是自带websocket支持的,而且其model的CRUD操作也自动支持pub/sub操作,一个Ajax请求无论是走HTTP协议还是websocket协议在controller是同一个处理入口,header/session都是一样的,这一特点真切让人感到体贴,不必再针对不同功能采用不同协议然后生成不同代码了。

  CAUTION:不能用于阿里云防火墙后面的应用服务 
  实测下来socket会频繁断掉重连,而且每次都是不同的IP地址,怀疑两点起因:
  ? 阿里防火墙专门针对HTTP无状态短连接设计,不允许出现长期的socket连接。
  ? 为了负载分担和恶意攻击防护,不同请求入口IP地址会变化。

  6. 孔雀翎-pm2 
  如果说Java的代码稳定是靠语法和Exception捕获来保证的,那么node.js的逻辑反其道行之-如果错了就尽快退出执行,反正catch回调函数抛出的异常就是水中月,进程生命周期管理最佳工具就是pm2,一行代码都不用写即可支持cluster运行模式,即使偶尔出错导致进程退出也会自动重启,确保服务不间断。

  7. 拳头-typescript 
  后台应用服务最关键的要求是什么?稳定,稳定,还是TMD的稳定。 
  面对一个过于自由没有类型检查的javascript语言,防范编码错误的最佳武器就是套上类型语言的盔甲,class /interface / extends / enum etc,少量代码时这是累赘,面对大量代码和复杂结构与逻辑时有语言的支撑才是保命的秘诀。

更多web前端学习信息,加群434623999

时间: 2024-11-03 18:42:31

node.js上除了Express还有哪些好用的web开发框架的相关文章

node.js 下依赖Express 实现post 4种方式提交参数

上面这个图好有意思啊,哈哈, v8威武啊.... 在2014年的最后一天和大家分享关于node.js 如何提交4种格式的post数据. 上上一篇说到了关于http协议里定义的4种常见数据的post方法 ,详细介绍请点击查看. 分别是这四种: www-form-urlencoded, form-data, application/json, text/xml Express 依赖 bodyParser 对请求的包体进行解析,默认支持:application/json, application/x-

Node.js开发入门—Express里的路由和中间件

我们已经基于Express写了HelloWorld示例,还使用express generator工具创建了一个HelloExpress项目,但有一些代码一直没有好好解释,这是因为它们牵涉到路由和中间件等概念,三言两语说不清楚,所以我专门用一篇文章来讲路由和中间件. 路由 通常HTTP URL的格式是这样的: http://host[:port][path] http表示协议. host表示主机. port为端口,可选字段,不提供时默认为80. path指定请求资源的URI(Uniform Res

Node.js笔记(0003)---Express框架Router模块学习笔记

这段时间一直有在看Express框架的API,最近刚看到Router,以下是我认为需要注意的地方: Router模块中有一个param方法,刚开始看得有点模糊,官网大概是这么描述的: Map logic to route parameters. 大概意思就是路由参数的映射逻辑 这个可能一时半会也不明白其作用,尤其是不知道get和param的执行顺序 再看看源码里面的介绍: Map the given param placeholder `name`(s) to the given callbac

Node.js上传文件

var formidable = require('formidable'); var util = require('util'); exports.upload = function(req,res){ var form = new formidable.IncomingForm(); form.encoding = 'utf-8'; form.uploadDir = "E:/file/upload";//目录需要已存在 /** * fields 表单中的其他属性 * files

在node.js上安装fis后显示fis不是内部命令,安装fis的环境变量配置问题

我们windows环境下的node.js 上安装各种工具的时候老是会遇到各种问题,下面是笔者在安装fis的时候出现的一个问题,后来研究后发现是环境变量配置的问题. 首先我在环境变量里边添加了一个变量名:NODE_PATH  变量值:C:\Program Files\nodejs\node_modules 笔者以为环境变量配置好了,但是在cmd中执行命令:npm install -g fis出现下边的状况: C:\Users\duanlin>npm install fis -g npm WARN

【node.js】安装express后,&#39;express&#39; 不是内部或外部命令的问题

因express默认安装是最新的版本,已经是4.x.x的版本.而最新express4.0+版本中将命令工具分出来了,所以必须要安装express-generator,执行: D:\TOOLS\NodeJs>npm install express-generator -g 然后再path中添加环境变量 C:\Users\lhk\AppData\Roaming\npm [node.js]安装express后,'express' 不是内部或外部命令的问题

在Node.js上搭建React.js开发环境

1.React.js的介绍: React 是一个用于构建用户界面的 JAVASCRIPT 库. React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图). React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源. React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它. 特点: 1.声明式设计 ?React采用声明范式,可以轻松描述应用. 2.高效 ?React通过对DOM的模拟,最大限

node.js下用Express搭建服务器(内含多种坑爹报错解决方法)

如题 环境:windows 8 64bit\node.js v0.10.33 我觉得有必要说一下,我把node.js没有装在默认目录下,而是自定义路径 E:\Program\nodejs 我觉得我后来遇到的很多问题与此有关. 好,然后我就开心地打开node,在cmd下输入 npm install -g express 它就果不其然地报错了,确切的错误我没记得,百度了下好像是-g那个参数的问题(开始不知道这个参数什么意思,后来才明白,就是装到node_gloabl目录下),所以我就把-g去掉,cd

Node.js开发入门—Express安装与使用

之前我们在安装完Node.js后直接写了个HelloWorld网站,这次呢,我们使用Node.js的Web框架Express来重写一下HelloWorld,看看有什么不同.同时我们还会重写之前的文件服务器,功能更完善而代码更简洁. 安装 express 为了重写我们的HelloWorld,我们需要安装Express模块.Express基于Node.js的一个Web框架,官方网站在这里:http://expressjs.com/.官网对Express的介绍是: Fast, unopinionate