基于backbone.js的许多框架的现实优势和劣势是什么?

时间:2012-06-01 09:36:29

标签: backbone.js javascript-framework

希望有人可以与一些最新出现的backbone.js变体分享他们的经验。 我在几个项目中对主干/下划线/需求有一些很好的经验,我希望为复杂的应用程序结构采取更高级的解决方案。

我知道以下框架可用:

可能我错过了一些。

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

但它很一般。我想知道是否有人可以使用这些框架与真实应用程序分享他们的经验。

选择一个而不是另一个有什么好处?例如,牵牛花什么时候会成为比chaplin更好的解决方案,或者为什么vetebrae更适合某些应用。

当然,明显的答案是“最好地满足您的需求”,但我缺乏这些框架的经验来了解他们的实力/目的/优势或首选方案。

谢谢!

编辑1: 发现这篇文章: Backbone.Marionette vs Backbone-Boilerplate

编辑2: Mathias schafer(卓别林)通过邮件回答:

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

Marionette肯定是最全面,最稳定的图书馆。它解决了使用Backbone进行JS应用程序开发的几个方面。例如,它有一个强大的视图层,Backbone本身完全无效。当然,您会发现某些方面无法满足您的要求,您可能觉得需要在Marionette周围建立一个结构。

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

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

这个结构有两个原则: - 模块化,解耦和沙盒 - 使用发布/订阅和中介进行跨模块通信

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

Chaplin还为View图层提供了增强功能,例如高度复杂的CollectionView,但总体上没有Marionette及其Regions和Layouts那么多。但是使用Chaplin Views提供的方法编写这样的元类相对容易。

5 个答案:

答案 0 :(得分:132)

大多数(全部?)你正在寻找的框架解决了同样的问题,但他们以稍微不同的方式实现目标略有不同。

我认为所有这些项目都可以解决这些类别中的问题,这是公平的:

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

我自2011年12月以来一直在建造的Marionette,也有一些非常明确的目标和理想:

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

我并不是说其他​​任何框架都没有这些相同的目标。但我认为木偶的独特性来自于这些目标的结合。

复合应用程序架构

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

基本思想是"撰写"您的应用程序的运行时体验和处理来自许多不必彼此了解的小型个体作品。他们将自己注册到整个复合应用程序系统,然后通过各种解耦消息和调用进行通信。

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

消息队列/模式

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

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

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

模块化

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

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


MyApp = new Backbone.Marionette.Application();

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

  // your module code goes here

});

(暂无此博文)

增量使用

这是我为木偶的每个部分烘焙的核心理念之一,我可以:不,全是或否#34;使用木偶的要求。

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

为此,我在Marionette中构建的大部分内容都是独立构建的,可以与Backbone的核心部分协同工作,并且可以更好地协同工作。

例如,几乎每个Backbone应用程序都需要在屏幕上的特定位置动态显示Backbone视图。当新的视图到位时,应用程序还需要处理关闭旧视图和清理内存。这是Marionette Region进场的地方。区域处理获取视图的样板代码,在其上调用render,并将结果填充到DOM中。然后关闭该视图并为您清理,前提是您的视图有一个"关闭"方法就可以了。


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

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

但是您不需要使用Marionette的观点来使用某个地区。唯一的要求是您在对象的原型链中的某个点上从Backbone.View扩展。如果您选择提供close方法,onShow方法或其他方法,Marionette's Region将在合适的时间为您拨打电话。

没有服务器锁定

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

  • ASP.NET MVC
  • Ruby on Rails
  • Ruby / Sinatra
  • NodeJS / ExpressJS
  • PHP / Slim
  • 爪哇
  • 二郎
  • ......还有更多

当涉及到在浏览器中运行时,JavaScript就是JavaScript。服务器端JavaScript也很棒,但它对我编写基于浏览器的JavaScript的方式没有影响或影响。

由于我构建的项目多样化以及客户使用的后端技术,我不能也不会出于任何原因将Marionette锁定到单个服务器端技术堆栈中。我不会提供样板项目。我不会提供红宝石宝石或npm包装。我希望人们了解Marionette并不需要特定的后端服务器。它是基于浏览器的JavaScript,而后端并不重要。

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

轻松更改默认值

在我努力减少样板代码并提供合理的默认值(这是我直接"借用"来自Tim Branyen的LayoutManager)的想法时,我认识到其他开发人员需要稍微使用不同于我的实现。

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

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


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

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

我甚至提供了一个带有v0.9的Marionette.Async插件,它允许你支持异步渲染视图。我一直努力让它变得尽可能简单,以取代Marionette中的默认行为。

代码配置

我是&#34;惯例而不是配置&#34;在某些情况下。这是完成任务的有效方式,而Marionette提供了一些 - 虽然不是太多,老实说。许多其他框架 - 尤其是LayoutManager - 提供了比Marionette更多的约定配置。

这是出于目的和意图。

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

为此,我采用了#34;代码作为配置&#34;接近木偶。我没有提供很多&#34;配置&#34; API,您可以在其中为对象文字提供可更改行为的静态值。相反,我记录了每个对象的方法 - 通过带注释的源代码和实际的API文档 - 旨在告诉你如何改变Marionette以你想要的方式工作。

通过为Marionette对象提供干净清晰的API,我创建了一种情况,即将特定对象或Marionette作为一个整体的行为替换相对简单且非常灵活。我牺牲了简单的&#34;配置API要求灵活地提供您自己的代码,以便按照您想要的方式工作。

您无法找到&#34;配置&#34;或&#34;选项&#34; Marionette的API。但是你会发现大量的方法,每个方法都有一个非常特殊的目的,带有干净的签名,可以很容易地改变Marionette的工作方式。

答案 1 :(得分:25)

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

所以,我对你的问题的回答是:从使用骨干开始,并问自己缺少什么,以及你对框架的期望是什么。如果您发现骨干遗漏了太多东西,那么在其他框架中搜索它们并选择最接近您需求的那个。如果你仍然对选择没有信心,也许骨干不适合你,你必须寻找其他解决方案(ember.js,sproutcore,ExtJs,JavaScript MVC都很好)。如果您有编写客户端应用程序的经验,那么您并不需要在所有框架上有经验来选择合适的应用程序(当然适合您)

答案 2 :(得分: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。最棒的是有各种各样的选择可以帮助您使用JavaScript(MVX)MVC模式进行编码。

答案 3 :(得分:13)

我在BenchPrep工作时开发了Luca framework,我们用它在backbone.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 base css类
  • Luca.Viewport和GridLayout组件设置为与bootstrap的响应式,流畅或静态网格系统一起使用。
  • 旨在为twitter引导程序组件提供一对一匹配,以将它们表示为可配置的主干视图

应用程序组件

  • 基于Backbone.Model的状态机提供getter / setter方法和属性更改事件作​​为应用程序控制流的样式
  • 集成控制器组件,用于隐藏/显示应用程序页面以响应Backbone.Router或State Machine事件
  • 集成收集管理器,用于跟踪您创建的集合,允许您对它们进行范围调整,对它们进行分组,为其分配默认参数
  • 一个套接字管理器,它是一个基于websocket服务的抽象层,它使得推送变得像Backbone.Event一样简单
  • 键盘事件路由器,用于触发响应此类事件的组件上的命名键事件

收集和模型增强

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

活动和挂钩

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

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

Ruby Gem

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

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

您不需要使用Rails或Sinatra。但如果你这样做,我已经包含了许多有用的东西:

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

开发工具

  • Luca应用程序可以在浏览器中启用带有Luca特定帮助程序的coffeescript控制台,以及有助于监视,检查和调试Luca应用程序和组件的命令

An example of the Luca in browser Development Console powered by CoffeeScript

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

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

  • 组件测试程序很快将与Jasmine集成,因此您可以在编辑代码时实时查看组件单元测试的结果

A screenshot of the component tester

Luca是一项正在进行中的工作,但它维护着一个稳定的API(还不是1.0)并且已经在几个大型生产应用程序中使用过。它绝对是一个非常固执的框架,但我正在努力使其更加模块化。我正在积极研究文档和示例组件。

答案 4 :(得分:11)

我是卓别林的合着者,我在Chaplin.js和Marionette.js之间进行了深入的比较:

http://9elements.com/io/index.php/comparison-of-marionette-and-chaplin/

这不是“枪战”,而是试图以平衡的方式解释这两种方法。