基于骨干.js的许多框架在现实世界中的优缺点是什么?[关闭]


186

希望有人可以与他们分享一些最新的新兴的ribs.js变体的经验。我在多个项目中的主干/下划线/需求方面都具有良好的经验,我想朝着针对复杂应用程序结构的更高级解决方案迈出下一步。

我知道可以使用以下框架:

可能我错过了一些。

这里有关于这些差异的简短介绍:

但这很笼统 我想知道是否有人可以使用这些框架在现实生活中分享他们的经验。

选择一个而不是另一个的好处是什么?何时,木偶戏是比卓别林更好的解决方案,或者为什么椎骨在某些应用中会更好?

当然,显而易见的答案是“ 使用最适合您的需求 ”,但是我缺乏这些框架的经验,无法了解其优势/目的/优势或首选方案。

谢谢!

编辑1: 找到了这篇文章: Backbone.Marionette vs Backbone-Boilerplate

编辑2: Mathias schafer(Chaplin)通过邮件回答:

简而言之,当前结构已经在生产中使用,因此它接近1.0版。我们不打算在1.0之前添加新的重大功能或对API进行更改。

木偶肯定是那里最全面,最稳定的图书馆。它解决了使用Backbone开发JS应用程序的几个方面。例如,它具有强大的视线层,主干网本身就完全留下了空白。当然,您会发现某些方面无法满足您的需求,并且您可能会觉得有必要在Marionette周围建立结构。

相比之下,卓别林专注于Backbone应用程序的一个相当小但非常重要的方面,即整个应用程序的结构和模块的生命周期。在这方面,卓别林非常善于表达,更像是框架而不是库(例如,“您的代码称为库,框架称为您的代码”)。卓别林提供了一些中心类,它们位于各个应用程序模块之上,并控制整个应用程序状态。例如,这为您的应用程序提供了像Ruby on Rails这样的常规结构。

在卓别林中,您声明了一些映射到控制器的路由,一旦路由匹配,卓别林便启动控制器。它还负责处理旧的控制器,以及显示和隐藏应该由控制器创建的主视图。这是基本思想,但卓别林会处理一些丑陋的细节,以使此过程顺利进行。

此结构附带两个原则:-模块化,解耦和沙箱处理-使用“发布/订阅”和“中介”的跨模块通信

当然,这些模式在软件开发领域并不是什么新事物,并且卓别林不是唯一将它们应用于Backbone.js应用程序的库。

卓别林还为View层提供了增强功能,例如高度复杂的CollectionView,但总体上不及Marionette及其Regions和Layouts。但是使用卓别林视图提供的方法来编写此类元类相对容易。


12
+1您的问题就来了。在过去的一两年中,某种形式的框架炒作使无数受架构启发的项目肿,而这些项目确实很难区分-每个项目都实施自己的做法,而且执行起来常常不肿。请注意,这是一条评论:)
kontur 2012年

Answers:


132

您正在寻找的大多数(所有?)框架都解决了相同的问题,但是它们以略有不同的方式实现了不同的目标。

我认为可以说所有这些项目都可以解决以下类别的问题:

  • 提供合理的默认设置
  • 减少样板代码
  • 在BackboneJS构建块的顶部提供应用程序结构
  • 提取作者在其应用中使用的模式

我从2011年12月开始建立的“木偶戏”还牢记一些非常不同的目标和理想:

  • 复合应用架构
  • 企业消息传递模式的影响
  • 模块化选项
  • 增量使用(无全有)
  • 没有服务器锁定
  • 轻松更改这些默认值
  • 代码作为配置/超配置

我并不是说其他​​框架都没有这些相同的目标。但我认为,木偶戏的独特之处在于这些目标的结合。

复合应用架构

我花了5年多的时间使用WinForms和C#在胖客户端,分布式软件系统中工作。我为台式机,笔记本电脑(智能客户端),移动设备和Web应用程序构建了应用程序,这些应用程序共享一个核心功能集并与同一服务器后端多次协作。在这段时间里,我了解了模块化的价值,并迅速地走下了复合应用程序设计的道路。

基本思想是“组合”您的应用程序的运行时经验,并从许多彼此不必了解的较小的单独部分中进行处理。他们在整个复合应用程序系统中注册自己,然后通过各种分离的消息和调用方式进行通信。

我在博客上写了一些有关此的内容,介绍了Marionette作为Backbone的复合应用程序体系结构:

消息队列/模式

相同的大型分布式系统还利用消息队列,企业集成模式(消息模式)和服务总线来处理消息。最重要的是,这对我解耦软件开发的方法产生了巨大影响。从这个角度,我开始看到单进程的内存中WinForms应用程序,不久,我的服务器端和Web应用程序开发就受到了影响。

这直接转化为我对Backbone应用程序设计的看法。我在Marionette中为高级Application对象以及您在应用程序中创建的每个模块提供了一个事件聚合器。

我考虑可以在模块之间发送的消息:命令消息,事件消息等。我还将服务器端通信视为具有这些相同模式的消息。有些模式已经进入了木偶戏,但还没有。

模块化

代码的模块化非常重要。对于任何规模和复杂性非常高的系统,必须创建具有单个焦点,定义明确的入口和出口点的小型,封装良好的软件包。

Marionette直接通过其module定义提供模块化。但是我也认识到有些人喜欢RequireJS并希望使用它。因此,我同时提供了标准版本和RequireJS兼容版本。


MyApp = new Backbone.Marionette.Application();

MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){

  // your module code goes here

});

(尚无与此相关的博客文章)

增量使用

这是我对木偶的每个部分都可以接受的核心哲学之一:对使用木偶没有“全有或全无”的要求。

骨干本身采用非常增量的模块化方法来处理所有的构建块对象。您可以自由选择何时使用。我坚信这一原则,并努力确保木偶的工作方式相同。

为此,我在Marionette中内置的大多数组件都是独立运行的,可以与Backbone的核心组件协同工作,甚至可以更好地协作。

例如,几乎每个Backbone应用程序都需要在屏幕上的特定位置动态显示Backbone视图。应用程序还需要处理关闭旧视图并在放置新视图时清理内存。这是木偶Region戏的出现地。区域处理获取视图,调用其上的render并将结果填充到DOM中的样板代码。然后,将关闭该视图并为您清理它,前提是您的视图上具有“关闭”方法。


MyApp.addRegions({
  someRegion: "#some-div"
});

MyApp.someRegion.show(new MyView());

但是您不需要使用木偶的视图来使用区域。唯一的要求是您要在对象原型链中的某个时刻从Backbone.View扩展。如果选择提供一个close方法,一个onShow方法,或其他木偶的地区将在适当的时候打电话给你。

没有服务器锁定

我在多种服务器技术之上构建Backbone / Marionette应用程序:

  • ASP.NET MVC
  • Ruby on Rails
  • 红宝石/西纳特拉
  • NodeJS / ExpressJS
  • PHP /苗条
  • 爪哇
  • Erlang
  • ... 和更多

当在浏览器中运行时,JavaScript是JavaScript。服务器端JavaScript也很棒,但是对于我编写基于浏览器的JavaScript的方式,其影响为零。

由于我构建的项目和客户使用的后端技术的多样性,因此我不能也不会将Marionette出于任何原因锁定在单个服务器端技术堆栈中。我不会提供样板项目。我不会提供红宝石宝石或npm包装。我想让人们理解,木偶不需要特定的后端服务器。它是基于浏览器的JavaScript,后端无关紧要。

当然,我完全支持其他人为其语言和框架提供软件包。我在Wiki中列出了这些软件包,并希望人们继续根据需要构建更多的软件包。但这是社区的支持,而不是木偶的直接支持。

轻松更改默认值

为了减少样板代码并提供合理的默认值(这是我直接从Tim Branyen的LayoutManager中“借用”的想法),我认识到其他开发人员需要使用与我略有不同的实现。

<script>默认使用Underscore.js模板为模板提供基于内联标签的渲染。但是您可以通过更改“ 木偶”中的Renderer和/或TempalteCache对象来代替它。这两个对象提供了渲染功能的核心,并且有Wiki页面显示了如何针对特定的模板引擎和不同的加载模板方式对此进行更改。

使用Marionette v0.9,它变得更加容易。例如,如果要用预编译的模板替换内联模板脚本块的使用,则只需在Renderer上替换一种方法:


Backbone.Marionette.Renderer.render = function(template, data){
  return template(data);
};

现在整个应用程序将使用您附加到视图template属性的预编译模板。

我什至提供了带有v0.9的Marionette.Async插件,该插件使您能够支持异步呈现视图。我一直在努力使替换木偶中的默认行为尽可能容易。

代码配置

在某些情况下,我喜欢“约定之上的配置”。这是完成工作的有力方法,并且木偶提供了一点点-老实说,虽然不是太多。与Marionette相比,许多其他框架(尤其是LayoutManager)在配置方面提供了更多约定。

这是有目的和有目的的。

我已经构建了足够的JavaScript插件,框架,附加组件和应用程序,以了解尝试使约定以有意义且快速的方式工作的痛苦。可以快速完成此操作,但通常以更改它为代价。

为此,我对“木偶戏”采用“编码即配置”方法。我没有提供很多“配置” API,您可以在其中提供具有静态值的对象常量,这些静态值会改变一系列行为。相反,我通过注释的源代码和实际的API文档来记录每个对象所具有的方法,目的是告诉您如何更改Marionette使其以所需的方式工作。

通过为Marionette对象提供简洁明了的API,我创造了一种情况,替换特定对象或Marionette的行为总体上相对简单且非常灵活。我牺牲了“简单”配置API调用的灵活性,因为它提供了自己的代码以使事情按您希望的方式工作。

在木偶中找不到“配置”或“选项” API。但是您会发现大量的方法,每种方法都有非常特定的目的,带有清晰的签名,可以轻松更改木偶的工作方式。


16
为什么这是评分最高的答案?它没有事件回答这个问题-它基本上是木偶的历史/广告……
杰西·特尔福德

@JessTelford您可能想重新阅读问题,这是一个非常好的答案。
2013年

@mor的问题是What is the benefit of choosing one over the other?-答案是Marionette [...] has a few very distinct goals and ideals in mind,它一次也无法与另一个框架进行比较。如果问题是“ 请解释每个框架可以做什么”,那么可以肯定,这是一个很好的答案。但事实并非如此。事实并非如此。
杰西·特尔福德2013年

@JessTelford这个问题显然要求多个答案。这说明了木偶所解决的优点和问题。阅读问题后,我发现此答案非常有帮助。我认为不一定是最好的,但是它仍然是一个很好的答案。哦,问题是:What are the strengths and weaknesses of...
2013年

@mor别误会我-这是对木偶的非常彻底和清晰的描述。我只是觉得它不能回答问题。无论如何,支持是一个很好的答案。
杰西·特尔福德2013年

25

我目前正在使用带有布局管理器模块和车把的主干作为模板引擎,我发现使用已经存在的Grails后端很容易设置一个小应用程序。在开始使用布局管理器之前,我阅读了有关Marionette和Chaplin的信息,在我看来,这两者都非常强大但又很复杂。然后我想起了为什么我最初选择了ribs.js:简单性。所有这些框架都增加了设计遗漏的主干。我并不是说框架很糟糕,但是如果我需要更复杂的东西,我将尝试其他项目,例如ember.js或萌芽核心,因为它们具有独特的代码库,其目标是开发人员的目标。在这里,我们在另一个框架之上。当然,骨干不仅是构建应用程序的骨干,而且还用于编写一些更强大的库,但是我认为唯一的缺点是视图层,因为它缺少布局管理器和嵌套视图的可能性。使用布局管理器可以很好地填补这一空白。

因此,我对您的问题的回答是:从按原样使用主干开始,并问自己缺少什么以及对框架的期望是什么。如果发现主干遗漏了太多东西,请在其他框架中搜索它们,然后选择最符合您需求的框架。而且,如果您仍然对选择没有信心,那么骨干网可能就不适合您,您还必须寻找其他解决方案(ember.js,prumpcore,ExtJs,JavaScript MVC都不错)。如果您有编写客户端应用程序的经验,那么您实际上并不需要所有框架的经验来选择合适的框架(当然,适合您)


13

我研究了使用Backbone.js构建的各种框架,并为HauteLook的一个项目构建了Vertebrae。该项目的目标包括...动态脚本加载,AMD模块格式,依赖项管理,使用大多数开源库进行构建,将代码组织在包中,针对一个或多个单页应用程序进行优化和构建,在完全缓存的服务器上托管(例如,没有服务器)端脚本仅使用数据API,而对我而言最有趣的是,使用行为驱动的项目开发。有关该项目的说明,位于:http : //www.hautelooktech.com/2012/05/24/vertebrae-front-end-framework-built-with-backbone-js-and-requirejs-using-amd/

我们的问题:

选定的库(jQuery,Underscore.js,Backbone.js,RequireJS,Mustache)提供模块加载,依赖管理,应用程序结构(用于模型,集合,视图和路由),与API的异步交互,各种实用程序和对象以管理异步行为,例如(承诺)延期,回调。完成框架所需的其余逻辑包括:

  • 用于管理单页应用程序状态的对象(模型);
  • 布局管理器以呈现,安排/转换和清除视图,以及
  • 控制器响应路线,获取/设置应用程序状态并将工作移交给布局管理器。

我们的解决方案(在Vertebrae中实现):

应用程序状态经理 -

应用程序管理器将数据存储在内存中,并将数据持久存储在浏览器存储中,以提供用于公共数据/元数据的资源。还提供数据(状态)以基于先前的交互(例如,选定的选项卡,应用的过滤器)来重构页面视图。应用程序状态管理器为资源检索状态提供了一种策略。打算充当状态机。

布局管理器 -

布局管理器具有一个或多个视图以及每个(渲染)视图的文档(DOM)目标。页面可能会在许多视图之间转换,因此布局管理器会跟踪视图状态,例如已渲染,未渲染,显示,未显示。您可以使用布局管理器来延迟加载和呈现(很可能是站点访问者很可能请求的)视图(例如,页面上的选项卡更改)。视图状态之间的转换由该对象管理。可以清除整个布局,以便删除视图对象及其绑定,从而为垃圾回收准备这些对象(防止内存泄漏)。布局管理器还与控制器通信视图状态。

控制器 -

控制器对象由路由处理程序函数调用,并负责获取相关状态(应用程序模型)以生成页面(布局)(还负责在路由更改时设置状态)。控制器将所请求页面的相关数据(模型/集合)和构造的视图对象传递给布局管理器。作为副作用,控制器的使用可防止路线对象膨胀和缠结。路由应映射到控制器,然后该控制器将启动页面视图,从而使路由处理功能保持精简。

Todos应用程序既以开发模式托管,又在Heroku上进行了优化。

其他框架中的许多概念都是借用的,例如,如Derick Bailey所指出的那样,需要破坏视图以预览内存泄漏,请参见http://lostechies.com/derickbailey/ ; Tim Branyen的版面管理器http://tbranyen.github.com/backbone.layoutmanager/

总而言之,Backbone.js旨在成为您应用程序中的工具,Backbone.js库并未提供构建应用程序所需的所有体系结构,但确实提供了与API和可靠代码结构的良好交互,以实现...视图(也像控制器一样起作用)以及数据层“模型和集合”,最后是“路由”。我们构建了Vertebrae,以实现项目目标,并决定提取代码作为框架供其他人使用,学习或其他。

我认为,您的问题的答案是从所有框架中学习并使用实现目标所需的内容,如果您发现项目目标与使用Backbone构建的框架之一非常匹配,那么很好,否则,您将构建自己的框架社区分享了很多很好的例子。或者,如果您发现自己在应用程序的方向上迷失了方向,那么请选择一些更自以为是和结构化的东西,也许是Ember.js。很棒的事情是,有很多选择可以帮助您使用(MVX)MVC之类的模式与JavaScript进行编码。


感谢您的详细回答。
danikoren 2012年

13

我在BenchPrep上工作时开发了Luca框架,我们使用它在eblob.js库的顶部开发了多个大型单页应用程序。

我使用ExtJS已有几年了,并且从该框架中窃取了我最喜欢的概念,例如组件驱动的体系结构,在该体系结构中,您将视图开发为独立组件,然后使用容器视图将它们与其他组件结合在一起。而且由于它很大程度上基于配置,因此在Luca中开发应用程序感觉很像使用JSON描述对象。

这种方法的优势之一是能够在多个应用程序或应用程序中不同位置重用组件,而使用Backbone的扩展仅需很小的更改即可。通过仅对JSON配置进行一些细微调整,就可以很容易地尝试组件的许多不同布局/表示形式。

除了广泛的帮助程序/实用程序功能外,Luca还提供了许多更高级别的Backbone派生工具,您可以用任何可以想像的方式将它们组合在一起以构建复杂的UI。

视图,组件,容器

  • 增强模型,视图,集合,路由器类
  • 配置选项,可促进模型,集合,视图,应用程序及其各自的管理器之间的通信。
  • 容器(拆分/列布局,网格布局,选项卡视图,卡片/向导视图)
  • 具有所有标准字段组件的FormView,以及用于与Backbone.Model同步的帮助器
  • GridView,用于从Luca.Collection生成可滚动的网格元素
  • CollectionView,用于基于集合生成视图
  • 工具栏/按钮

免费的Twitter Bootstrap样式和标记

  • Luca在Twitter引导框架中的表现非常出色。只需设置Luca.enableBootstrap = true,并包括CSS,您的组件(例如选项卡视图,工具栏,按钮,表单,字段,网格等)将自动使用Twitter Bootstrap兼容的标记和CSS类约定。
  • 使用Grid系统进行布局,并以一种智能的方式响应大多数Bootstrap基本CSS类
  • Luca.Viewport和GridLayout组件已设置为可与Bootstrap的响应式,动态或静态网格系统一起使用。
  • 旨在为Twitter引导程序组件提供一对一匹配,以将它们表示为可配置的主干视图

应用程序组件

  • 基于Backbone.Model的状态机提供getter / setter方法和属性更改事件,作为一种应用程序控制流程
  • 集成控制器组件,用于响应Backbone.Router或State Machine事件来隐藏/显示应用程序页面
  • 集成的收集管理器,可以跟踪您创建的收集,使您可以对它们进行范围划分,分组,为它们分配默认参数
  • 一个套接字管理器,它是websocket服务之上的一个抽象层,使推送与Backbone一样容易。
  • 键盘事件路由器,该键盘事件路由器在关心响应此类事件的组件上触发命名的按键事件

集合和模型增强

  • 集合基于骨干查询,它提供了与mongoDb非常相似的查询接口
  • 只需通过设置collection.localStorage = true即可启用本地存储Backbone.sync
  • 自动填充其数据在页面加载时引导的集合
  • 缓存的方法/计算的属性。缓存收集方法的结果,并使缓存过期以响应集合或其模型上的更改/添加/删除事件
  • 模型上的计算属性。基于复杂函数构建属性,并根据更改自动更新计算值

事件和挂钩

与股票Backbone组件相比,Luca组件发出的事件更加自由。它们将发出类似before:initialize,after:initialize,before:render,after:render,激活,first:activation,deactivation,first:deactivation之类的事件,这使您可以更精细地调整组件的行为。另外,通过在视图的@hooks porperty中定义一个事件,该事件将自动为您调用一个类似名称的函数(如果存在)。这样可以防止大量回调样式代码,从而提高了可读性。

您还可以配置Luca.Events类以将事件发布到全局发布/订阅通道,这使构建大型应用程序更加容易,并有助于模块间的通信。

红宝石宝石

Luca是专门针对Rails和Sinatra API进行开发的,因此目前已针对特定堆栈进行了优化,但绝不会将您锁定在特定服务器中。

Luca作为Ruby Gem的一部分进行分发,该Ruby Gem配置为可在资产管道上工作,或者作为可下载的JS文件。

您不需要使用Rails或Sinatra。但是,如果您这样做,我将提供很多有用的信息:

  • 扩展名为.luca的文件将通过JST样式变量插值作为HAML处理。(相当于.jst.ejs.haml)通过资产管道
  • 浏览器的测试工具,或无头的基于Jasmine的单元测试,以及许多Backbone和Underscore测试助手。
  • Luca附带的开发工具集的API端点(稍后会对此进行更多介绍)
  • 一个API端点,允许您以最少的配置将Redis用作Luca.Collection的无模式存储引擎

开发工具

  • Luca应用程序可以使用特定于Luca的帮助器和命令启用浏览器中的咖啡脚本控制台,以帮助监视,检查,调试Luca应用程序和组件

由CoffeeScript支持的浏览器开发控制台中的Luca示例

  • 借助Rails Gem和Luca基于CodeMirror的组件编辑器,您可以使用Coffeescript直接在浏览器中编辑Luca Framework的源代码以及特定于应用程序的组件。您将看到响应您的编辑的即时反馈,受影响对象的实例将使用更新的原型进行刷新,并且您可以将更改保存到磁盘。

  • 组件测试器是一个实时沙箱,用于单独处理组成应用程序的组件。它为您提供了用于修改组件原型,设置其依赖关系以及配置组件的工具。每次进行编辑时,该组件都会立即重新渲染。您可以直接在浏览器中查看和编辑组件生成的标记以及CSS,并立即查看所做的更改。这使其成为非常有价值的实验工具。

  • Component Tester即将与Jasmine集成在一起,因此您可以在编辑代码时实时查看组件单元测试的结果。

组件测试器的屏幕截图

Luca尚在开发中,但保持了稳定的API(尚未1.0),并已在多个大型生产应用程序中使用。绝对是一个非常自以为是的框架,但我正在努力使其更具模块化。我正在积极研究文档和示例组件。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.