在服务器和客户端上呈现Backbone.js应用程序

6
假设我有一个使用Backbone.js和Handlebars构建的Web应用程序。作为服务器,我正在使用Node.js。现在我想在服务器端和客户端上进行渲染。
当第一次请求路由时,出于性能原因,服务器应该进行渲染。之后,所有后续操作都应该导致客户端渲染。
这意味着我必须能够在客户端和服务器上以完全相同的方式渲染任何页面。两端都必须支持相同类型的路由。
我该如何完成这个任务?
目前,我已经看了AirBnb的rendr项目,但这肯定会将我与Backbone.js联系起来(我不确定我是否想一直坚持使用Backbone.js),而且似乎还没有完全完成。至少,AirBnb尚未推荐它用于生产环境。
还有其他关于如何完成此任务的想法吗?
作为一个子问题,我可能还可以问:在服务器和客户端之间分享JavaScript代码的首选方法是什么?对此,我也知道piler,但我想象可能有更好的解决方案可用。
有任何提示吗?

1
除了子问题之外,这可能是 https://dev59.com/f2ox5IYBdhLWcg3wtmc1?rq=1 的重复。您会在那里找到一些关于JS模板语言的好讨论。别忘了模板引擎选择器!http://garann.github.io/template-chooser/ - Noah C
1个回答

11

我正在开发一个应用程序,它可以实现这个功能。如果您不想使用rendr,那么您需要编写自己版本的一些重要部分。据我所知,目前您的选择是使用rendr或者自行开发。以下是一些杂项提示。

  • 我们在服务器端使用cheerio进行DOM操作,因此当视图在服务器上呈现时,this.$el是一个cheerio元素实例。在浏览器中,它是jQuery。
  • 您不需要在服务器端进行事件委派和绑定。我们的代码当前技术上也在这样做,但这是没有意义的,一个更清晰的解决方案会避免在服务器上进行该操作。
  • 一旦您在浏览器中拥有了经过服务器渲染的HTML,您需要一种方法将一组大型嵌套的视图实例与它们在大型嵌套的DOM树中对应的元素进行连接。我们有一个自己开发的解决方案,但是Backbone.View.setElement是核心,您需要编写一些代码来实现这一点。
  • 目前我们仍然在浏览器中重新渲染,尽管可能有一种更好的方法可以将视图实例给予一些选项(包括预先呈现的DOM节点)在构造函数中,并在不重新渲染的情况下正确地进行连接。然而,这是读者需要自己完成的练习。:-)
  • 我们还通过<script>标签发送我们需要的原始数据作为JSON,因此我们既有服务器渲染的HTML(用于感知性能),也有可用的原始数据作为JSON,以便我们可以实例化和操作我们的backbone模型和视图。同样,您需要编写一些代码来管理这种情况。
  • 我们使用browserify在服务器端和浏览器端进行捆绑和共享代码。我们所有的JavaScript都被编码为CommonJS模块。
  • 我们在视图父类中有一个基本的isBrowser()函数,以便知道什么时候应该运行仅限于浏览器的代码用于事件绑定等。

总之,不管怎样,在使用这种方式工作了很多个月后,我认为backbone不太适合这种范例。backbone的许多核心概念都是可行的,但它不能很好地将视图实例映射到预渲染的DOM节点。从JSON引导模型和集合更容易,但视图层可能需要进行重大改进以在这种风格下有效地操作。


你是怎么做到的 我们使用cheerio进行服务器端DOM操作,因此当视图在服务器上渲染时,this.$el是一个cheerio元素实例。在浏览器中,它是jQuery 的? - eugene
你是否考虑使用 "prerender"(https://github.com/prerender/prerender)?我跟着你的步子,但卡在第一步。我的 HTML 里有一个 JavaScript 区块,所有东西都从那里开始。我该如何像浏览器一样在服务器端执行脚本块中的 JavaScript?我感到困惑... 你能给点提示吗? - eugene
不,因为我的服务器端是node,所以想法是在node中呈现HTML,而不使用像phantomjs这样的服务器端浏览器解决方案,这正是“同构”的目标。但是大多数JavaScript代码目前并不是同构的 - 您需要设计您的应用程序以符合该风格。 - Peter Lyons
但是您能否详细说明将Cheerio连接到Backbone而不是jQuery所使用的技术? - iMoses
在我们的基础视图类的 init 方法中,我们设置了 this.$el = cheerio("<div></div>")。我认为这基本上就是全部内容了。 - Peter Lyons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接