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

希望有人可以分享一些最新的backbone.js变种的经验。 在几个项目中,我对主干/下划线/需求有一些很好的经验,并且我希望为复杂的应用程序结构迈出更高级的解决scheme。

我知道以下框架可用:

  • 木偶
  • Geppetto(基于木偶)
  • 卓别林 , 卓别林 – chaplin-boilerplate
  • 椎体
  • 布局pipe理
  • 胸部
  • 灵气
  • 卢卡
  • Singool
  • 堆栈中
  • 骨干网UI
  • 废船

  • 顺便说一句 – 大规模项目的优秀起点

可能我错过了一些。

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

  • speakerdeck谈话链接

但这是非常普遍的。 我想知道是否有人可以使用这些框架分享他们的实际应用程序的经验。

select一个优于另一个的好处是什么? 例如,什么时候牵线木偶可以成为比chaplin更好的解决scheme,或者为什么vetebrae更适合某些应用。

当然,显而易见的答案将是“ 使用最适合您的需求的东西 ”,但是我缺乏这些框架的经验来了解他们的优势/目的/优势或首选scheme。

谢谢!

编辑1:find这个职位: Backbone.Marionette与Backbone-Boilerplate

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

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

木偶是当然最全面和最稳定的图书馆。 它使用Backbone解决了JS应用程序开发的几个方面。 例如,它有一个强大的视图层,骨干本身完全无效。 当然,你会发现有些方面不能满足你的要求,你可能会觉得有必要build立一个围绕木偶的结构。

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

在卓别林,你声明了一些映射到控制器的路线,卓别林一旦路线匹配就启动控制器。 它还处理旧控制器的处置,以及控制器应该创build的主视图的显示和隐藏。 这是基本的想法,但卓别林照顾丑陋的细节,使其顺利运行。

有两个主体与此结构相伴随: – 模块化,解耦和沙箱化 – 使用发布/订阅和介体的跨模块通信。

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

卓别林还为视图层提供了增强function,例如高度复杂的CollectionView,但总体上不像制作区域和布局的木偶。 但是使用Chaplin Views提供的方法来编写这样的元类是相对容易的。

你所看到的大部分(所有?)框架解决了同样的问题,但是它们以稍微不同的方式做了稍微不同的目标。

我认为所有这些项目都能解决这些问题是公平的:

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

我自2011年12月以来一直在build造的木偶,也有一些非常不同的目标和理想:

  • 复合应用程序架构
  • 企业消息传递模式影响
  • 模块化选项
  • 增量使用(无需全部或无要求)
  • 没有服务器locking
  • 可以轻松更改这些默认设置
  • 代码为configuration/重configuration

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

复合应用架构

我花了超过5年的时间在使用WinForms和C#的厚客户端,分布式软件系统上工作。 我为台式机,笔记本电脑(智能客户端),移动设备和networking应用程序构build了应用程序,所有这些应用程序共享一个核心function集,并且多次使用相同的服务器后端。 在这段时间里,我学会了模块化的价值,并迅速走上了复合应用devise的道路。

基本的想法是“编写”你的应用程序的运行时体验,并且处理掉许多小而独立的部分,而这些部分不一定彼此了解。 他们自己注册整个复合应用系统,然后通过各种不同的消息和通话方式进行通信。

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

消息队列/模式

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

这已经直接转化为我如何看待Backbone应用程序devise。 我在Marionette中提供了一个事件聚合器,用于高级应用程序对象以及在应用程序中创build的每个模块。

我想到了可以在模块之间发送的消息:命令消息,事件消息等等。 我也把服务器端通信看作是具有相同模式的消息。 一些模式已经进入了木偶,但有些还没有。

模块化

代码的模块化非常重要。 创build具有明确定义的入口点和出口点的小型,封装良好的封装对于任何尺寸和复杂度都很高的系统来说是必须的。

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

 MyApp = new Backbone.Marionette.Application(); MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){ // your module code goes here }); 

(没有可用于此的博客文章)

增量使用

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

骨干本身需要一个非常增量和模块化的方法来处理所有的构build块对象。 你可以自由select你想使用哪个,什么时候使用。 我坚信这个原则,并努力确保木偶工作方式相同。

为此,我内置的大部分木偶片都是独立的,与骨干的核心部分一起工作,甚至更好地合作。

例如,几乎每个Backbone应用程序都需要在屏幕上的特定位置dynamic显示Backbone视图。 应用程序还需要处理closures旧视图和清理新内存时的内存。 这是木偶Region进场的地方。 一个区域处理样板视图的代码,调用渲染器,并将结果填充到DOM中。 然后closures视图并清理它,只要你的视图有一个“closures”的方法就可以了。

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

但是你不需要使用木偶的意见来使用一个地区。 唯一的要求是你在对象的原型链中的某个点从Backbone.View扩展。 如果您select提供close方法, onShow方法或其他方法,则Marionette地区会在适当的时间为您打电话。

没有服务器locking

我在各种各样的服务器技术之上构buildBackbone / Marionette应用程序:

  • ASP.NET MVC
  • Ruby on Rails
  • Ruby / Sinatra
  • NodeJS / ExpressJS
  • PHP / Slim
  • Java的
  • 二郎神
  • … 和更多

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

由于我构build的项目和我的客户使用的后端技术的多样性,出于任何原因,我不能也不会将Marionettelocking在单个服务器端技术堆栈中。 我不会提供一个样板工程。 我不会提供ruby或npm包。 我希望人们理解,木偶不需要特定的后端服务器。 这是基于浏览器的JavaScript,而后端并不重要。

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

轻松更改默认值

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

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

随着木偶的v0.9,它变得更加容易。 例如,如果要用预编译的模板replace使用内联模板脚本块,则只需replaceRenderer上的一个方法:

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

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

我甚至提供了一个v0.9的Marionette.Async插件,允许你支持asynchronous渲染视图。 我一直努力使其尽可能简单地取代木偶中的默认行为。

代码作为configuration

在某些情况下,我是“惯例重于configuration”的粉丝。 这是一个完成任务的强大方式,而木偶提供了一点点 – 虽然不是太多,诚实。 许多其他的框架,尤其是LayoutManager,比起Marionette,可以提供更多的configuration。

这是有目的和意图完成的。

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

为此,我对“木偶”采取“代码configuration”的方法。 我没有提供很多“configuration”API,您可以在其中提供一个对象文字,其中的静态值可以改变一些行为。 相反,我通过注释的源代码和实际的API文档来logging每个对象所具有的方法,目的是告诉您如何更改Marionette以按照您的方式工作。

通过为木偶物体提供一个干净清晰的API,我创造了一种情况,即将一个特定物体或木偶的行为作为一个整体来replace是相对简单和非常灵活的。 我牺牲了“简单的”configurationAPI调用,以提供您自己的代码,使您的工作方式,你想要的灵活性。

在Marionette中找不到“configuration”或“选项”API。 但是你会发现大量的方法,每个都有一个非常特定的目的,干净的签名,可以很容易地改变木偶的工作方式。

我目前正在使用布局pipe理器模块和handlebars作为模板引擎的主干,我发现使用已经存在的Grails后端build立一个小应用程序非常容易。 在开始使用布局pipe理器之前,我读了关于木偶和卓别林的故事。 然后我想起了为什么我最初selectbackbone.js:简单。 所有这些框架都增加了devise中遗留的骨干。 我并不是说框架是坏的,但如果我需要更复杂的东西,我会尝试其他项目,比如ember.js或sproutcore,因为它们有一个独特的代码库,在开发人员的脑海中编写一个目标。 在这里我们有另外一个框架。 当然,骨干不仅是构build应用程序的骨干,也是编写一些function更强大的图书馆的主干,但是我认为唯一不好的就是视图层,因为缺less布局pipe理器和嵌套视图的可能性。 与布局经理的差距填补相当不错。

所以,我对你的问题的回答是:从现在起使用骨干开始,问自己缺less什么以及对框架有什么期望。 如果你发现有很多东西被遗漏,那么去其他框架去search,然后select最接近你需要的。 如果你仍然对自己的select没有信心,也许骨干不适合你,你必须看看其他解决scheme(ember.js,sproutcore,ExtJs,JavaScript MVC都很好)。 如果您有编写客户端应用程序的经验,那么您并不需要在所有框架上有经验来select正确的(当然,对于您)

我研究了使用Backbone.js构build的各种框架,并在HauteLook中为一个项目构build了Vertebrae。 该项目的目标包括…dynamic脚本加载,AMD模块格式,依赖pipe理,与大多数开源库build立,组织代码包,优化和build立一个或多个单页面的应用程序,主机完全caching的服务器,例如没有服务器只使用数据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)提供模块加载,依赖pipe理,应用程序结构(模型,集合,视图和路由),与API的asynchronous交互,各种实用程序和对象来pipe理asynchronous行为,例如(承诺)延期,callback。 完成框架所需的其余逻辑包括:

  • 一个对象(模型)来pipe理单页面应用程序的状态;
  • 布局经理来介绍,安排/转换和清晰的观点,以及
  • 控制器响应路线,获取/设置应用程序状态,并将工作交给布局pipe理器。

我们的解决scheme (在Vertebrae中实施):

应用状态pipe理器

应用程序pipe理器将数据存储在内存中,并将数据保存在浏览器存储中以提供常用数据/元数据的资源。 还提供数据(状态)以基于先前的交互(例如选定的选项卡,应用的filter)来重构页面浏览。 应用程序状态pipe理器为检索状态提供资源策略。 意味着作为一个国家机器。

布局pipe理器

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

控制器

控制器对象由路由处理函数调用,负责获取相关状态(应用模型)生成页面(布局)(也负责设置路由改变时的状态)。 控制器将相关数据(模型/集合)传递给布局pipe理器,并为请求的页面构造视图对象。 作为一个副作用,控制器的使用可以防止路由对象变得臃肿和纠结。 路线应映射到控制器,然后启动页面视图,保持路线处理function的精益。

Todos应用程序在dev模式下进行托pipe,并在Heroku上进行了优化…

其他框架中的许多概念都是借用的,例如Derick Bailey指出的预览内存泄漏的缺点 – http://lostechies.com/derickbailey/ ; Tim Branyen的布局pipe理器http://tbranyen.github.com/backbone.layoutmanager/

总之,Backbone.js是为了在您的应用程序的工具Backbone.js库不提供您将需要build立一个应用程序的所有体系结构,但确实提供良好的交互与API和可靠的代码结构…视图(也像控制器一样)和数据层模型和集合,最后是路由。 我们构build了Vertebrae来实现我们项目的目标,并决定将代码作为一个框架提供给其他人使用,学习或其他任何东西。

在我看来,你的问题的答案是从所有的框架中学习,如果你发现你的项目目标与用Backbone构build的框架之一密切相关,那么你可以使用你需要的来实现你的目标,否则就build立你自己的框架社区也有很好的例子。 或者如果你发现自己在应用程序的方向上有点迷茫,那么select一些更加自以为是的,也许是Ember.js的结构。 最重要的是有很多种select可以帮助您使用JavaScript(MVX)MVC模式进行编码。

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

我曾经和ExtJS工作了好几年,并从这个框架中偷走了我最喜欢的概念,比如组件驱动架构,在这个架构中,您将视图作为独立组件进行开发,然后使用容器视图将其与其他组件结合在一起。 而且由于它主要是基于configuration,所以在Luca开发一个应用感觉很像用JSON描述一个对象。

这种方法的一个好处是能够跨越多个应用程序或应用程序中的不同位置重复使用组件,只需使用Backbone的扩展进行小的更改。 通过对JSONconfiguration进行微小的调整,也可以非常容易地尝试许多不同的布局/组件演示。

除了广泛的帮助/实用function之外,Luca还提供许多更高级别的骨干衍生产品,您可以用任何方式拼凑在一起,构build复杂的用户界面。

视图,组件,容器

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

Twitter Bootstrap样式和免费标记

  • Luca在Twitter引导框架中performance得非常好。 只需设置Luca.enableBootstrap = true,并包括CSS,你的组件(如标签视图,工具栏,button,窗体,字段,网格等)将自动使用Twitter Bootstrap兼容标记和CSS类约定。
  • 使用网格系统进行布局,并以智能的方式响应大多数的引导基础CSS类
  • Luca.Viewport和GridLayout组件设置为与引导程序的响应式,stream动式或静态网格系统一起工作。
  • 旨在为twitter引导组件提供一对一的匹配,将其表示为可configuration的Backbone Views

应用程序组件

  • 基于Backbone.Model的状态机提供了getter / setter方法和属性变化事件作为应用程序控制stream的一种风格
  • 集成控制器组件,它隐藏/显示应用程序的页面,以响应Backbone.Router或状态机事件
  • 集成的集合pipe理器跟踪您创build的集合,允许您对其进行范围,对它们进行分组,为其分配默认参数
  • 一个Socketpipe理器,它是websocket服务之上的一个抽象层,它使得像Backbone.Event一样简单
  • 一个键盘事件路由器,它触发组件上的命名键事件,这些组件关心响应这样的事件

集合和模型增强

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

事件和挂钩

与股票骨干组件相比,Luca组件更容易发生事件。 它们将像以前一样发出事件:初始化,之后:初始化,之前:渲染,之后:渲染,激活,第一:激活,停用,第一:停用,这可以让你更精细地调整组件的行为。 另外,通过在视图上的@hooks porperty中定义一个事件,如果它存在的话,它会自动调用一个类似命名的函数。 这防止了许多提高可读性的callback样式代码。

您还可以configurationLuca.Events类以将事件发布到全局发布/订阅通道,这使得构build大型应用程序变得更为简单,并有助于模块之间的通信。

Rubygem

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

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

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

  • 具有.luca扩展名的文件被处理为具有JST样式variables插值的HAML。 (相当于.jst.ejs.haml)
  • 浏览器的testing工具,或基于无头茉莉花的unit testing以及许多Backbone和Underscoretesting助手。
  • Luca附带的开发工具集的API端点(稍后会详细介绍)
  • 一个API端点,允许您以最less的configuration将Redis作为Luca.Collection的无模式存储引擎

开发工具

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

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

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

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

  • Component Tester将很快与Jasmine集成,以便您可以在编辑代码时实时查看组件unit testing的结果

组件测试器的屏幕截图

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

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

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

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