Brisket框架与Colony案例:构建高效同构应用的探索
1. Brisket框架特性解析
Brisket是一个强大的框架,为开发者提供了诸多便利和灵活的开发方式。
1.1 路由处理
Brisket的路由处理程序允许开发者根据不同的路由规则执行相应的操作。以下是一个示例:
const RouterBrewery = require('path/to/app/RouterBrewery');
const Example = require('path/to/app/Example');
const ExampleView = require('path/to/app/ExampleView');
const ExampleRouter = RouterBrewery.create({
routes: {
'examples/:exampleId': 'example'
},
example: function(exampleId, layout, request, response) {
if (!request.cookies.loggedIn) {
response.redirect('/loginpage');
}
request.onComplete(function() {
layout.doSomething();
});
const example = new Example({ exampleId });
example.fetch()
.then(() => {
const exampleView = new ExampleView({ example });
exampleView.on('custom:event', console.log);
return exampleView;
});
}
});
这个路由处理程序主要负责选择要渲染的视图,同时还使用了事件冒泡,根据cookie做出决策,并在路由对用户可见时执行一些操作。
1.2 模板语言选择
Brisket允许开发者使用任何模板语言。默认情况下,它提供了一个简单而强大的
StringTemplateAdapter
,但开发者可以通过继承
Brisket.Templating.TemplateAdapter
并实现
templateToHtml
方法来构建自定义的模板适配器。以下是一个简单的Mustache模板适配器的示例:
const MustacheTemplateAdapter = TemplateAdapter.extend({
templateToHTML(template, data, partials) {
return Mustache.render(template, data);
}
});
const MustacheView = Brisket.View.extend({
templateAdapter: MustacheTemplateAdapter
});
改变视图的模板引擎只需要几行代码,并且继承自该视图的所有视图都将使用相同的模板引擎。
1.3 跨环境一致的API
Brisket提供了跨环境一致的API,帮助开发者专注于应用逻辑,而不必担心代码运行的环境。
- 模型和集合 :Brisket提供了与环境无关的Backbone模型和集合实现。在客户端和服务器端,模型都使用jQuery来获取数据。以下是一个Brisket模型的示例:
const Side = Brisket.Model.extend({
idAttribute: 'type',
urlRoot: '/api/side',
parse: function(data) {
return data.side;
}
});
目前,团队正在努力摆脱对jQuery的依赖,客户端将探索使用新的Fetch API,服务器端则希望切换到http或request。
-
视图生命周期
:为了使视图与环境无关,Brisket劫持了视图的
render方法,并执行以下渲染工作流程:-
调用视图的
beforeRender回调。 - 将视图的模型和视图逻辑合并为一个数据对象。
- 使用视图的模板适配器、模板和数据渲染模板到视图的内部元素。
-
调用视图的
afterRender回调。
-
调用视图的
此外,Brisket视图还有一个
onDOM
回调,当视图进入页面的DOM时,可在客户端对视图进行更改。
以下是视图生命周期的流程图:
graph TD;
A[调用beforeRender] --> B[合并数据];
B --> C[渲染模板];
C --> D[调用afterRender];
D --> E{是否在客户端};
E -- 是 --> F[调用onDOM];
E -- 否 --> G[结束];
1.4 子视图管理
在标准的Backbone应用中,子视图管理可能会很棘手,容易导致内存泄漏。Brisket提供了子视图管理系统,帮助开发者管理内存和显示子视图。该系统处理父视图和子视图的关联,并在路由切换时清理视图。
1.5 跨环境工具特性
Brisket还提供了一些跨环境的工具特性,如重定向和请求引用。
-
重定向 :Brisket的响应对象提供了一个
redirect方法,与Express引擎的响应对象具有相同的签名。在服务器端,它会重定向到新的URL;在浏览器中,调用response.redirect会触发新页面的全页加载,并使用window.location.replace替换浏览器历史记录中的原始URL。 -
请求引用 :在传统网站中,请求的引用可以通过Express中间件的
request.referrer或浏览器的document.referrer属性获取。在SPA中,document.referrer在初始页面加载时是正确的,但在导航到新页面后可能会出错。Brisket的request.referrer属性提供了标准化的引用。
2. Colony案例:无Node的同构应用构建
Colony是一个全球电影流媒体平台,面临着将传统服务器渲染的可索引网站与单页应用相结合的挑战。
2.1 问题提出
Colony的视频点播业务模式与Netflix等竞争对手不同,采用按使用付费的交易模式,内容对公众开放浏览和购买。同时,产品需要一个动态的用户界面,以反映复杂的应用状态变化。最初使用ASP.NET MVC构建的原型无法满足需求,团队希望将前端转换为单页应用,同时避免SEO问题,并且不使用Node.js后端和重新构建整个应用。
为了实现这一目标,团队需要解决以下问题:
1. 是否存在一种模板语言,在C#和JavaScript中都有实现,并且是“无逻辑”的?
2. 如果前端和后端都需要某个组件,能否用JSON等与语言无关的数据格式表示?
3. 能否将一种语言编写的代码自动转换为另一种语言?
2.2 模板选择
团队选择了Handlebars作为模板语言,因为它具有严格的无逻辑性质和有限的作用域。Handlebars最初是为JavaScript编写的,但现在几乎所有流行的服务器端编程语言都有实现,其中C#的实现是
Handlebars.Net
。
团队的前端采用模块化设计,每个视图由一系列可重用的模块组成。使用共享的模板语言和数据结构后,前端和后端可以共享这些模块,并以相同的方式渲染。
2.3 数据结构设计
为了避免视图模型的临时性质和数据结构不清晰的问题,团队设计了一个“全局”数据结构,用于表示整个应用的状态:
{
Site: {...},
Entry: {...},
User: {...},
ViewState: {...},
Module: {...}
}
-
Site对象包含与整个网站或应用相关的数据,如静态文本、Google Analytics ID等。 -
Entry对象包含当前正在查看的资源的数据,如页面或特定电影。 -
User对象包含已登录用户的非敏感数据,如姓名、头像和电子邮件地址。 -
ViewState对象用于反映视图的当前渲染状态,对于在后端通过URL渲染复杂状态至关重要。 -
Module对象包含与模块相关的数据。
通过这种数据结构,后端将数据从数据库映射并传递给Handlebars进行渲染,前端通过REST API接收数据并传递给Handlebars,最终提供给Handlebars的数据是相同的。
综上所述,Brisket框架为开发者提供了灵活的开发方式和跨环境的一致性,而Colony案例展示了如何在不使用Node.js的情况下构建同构应用,为开发者提供了有价值的参考。未来,Brisket团队将继续改进框架,以提供更好的用户体验和开发效率。
Brisket框架与Colony案例:构建高效同构应用的探索
3. Brisket框架的其他特性与灵活性
Brisket框架在设计上极为注重灵活性,以实现与第三方工具的高度互操作性。
3.1 避免对开发的限制
Brisket尽量减少构建应用的规则,为集成第三方代码提供了充足的空间,即使这些代码并非完全同构。这使得开发者在使用各种第三方工具时,框架不会成为阻碍。
3.2 ClientApp和ServerApp类
团队在开发BloombergView时,发现jQuery插件通常不具备同构友好性,只能在客户端正常工作。为了解决这个问题,Brisket提供了
ClientApp
和
ServerApp
基类,开发者可以继承这些类,将它们作为特定环境的初始化器。例如,可以在这些类中设置特定环境的日志记录、初始化jQuery插件或根据环境启用/禁用某些功能。
3.3 布局模板
Brisket提供了一个继承自
Brisket.View
的
Layout
类,布局模板用于定义页面的
<html>
、
<head>
和
<body>
标签。目前,虽然多布局仅在服务器端可用,但由于布局模板本质上是标准的标记,因此非常适合放置广告、跟踪像素等第三方嵌入代码。
以下是Brisket框架特性的总结表格:
| 特性 | 描述 |
| ---- | ---- |
| 路由处理 | 根据路由规则执行操作,处理视图选择、事件冒泡、cookie判断等 |
| 模板语言选择 | 支持任意模板语言,可自定义模板适配器 |
| 跨环境一致的API | 模型、集合和视图在不同环境下有一致的使用方式 |
| 子视图管理 | 解决Backbone应用中子视图管理难题,避免内存泄漏 |
| 跨环境工具特性 | 提供重定向和请求引用等跨环境功能 |
| 灵活性设计 | 减少开发规则,便于集成第三方代码 |
| ClientApp和ServerApp类 | 作为特定环境的初始化器,处理客户端和服务器端特定代码 |
| 布局模板 | 定义页面结构,适合放置第三方嵌入代码 |
4. Brisket框架的经验教训与未来展望
在使用Brisket框架的过程中,团队积累了一些宝贵的经验教训,同时也对框架的未来发展有了明确的规划。
4.1 经验教训
- 避免单块客户端捆绑 :随着应用和代码包的增长,单块客户端捆绑会导致初始页面加载变慢。团队正在开发新功能,以更轻松地将Brisket应用拆分为更小的捆绑包。
- 防止内存泄漏 :在编写单页应用时,开发者有时会忘记代码在服务器端也会运行,使用单例或不清理事件绑定可能会导致内存泄漏。在同构应用中,必须遵循良好的编码实践。
- 自建框架的挑战 :虽然构建自己的框架令人兴奋,但在紧迫的截止日期下,如果框架缺少某些工具,实现功能会变得困难。不过,每一次的挫折都促使Brisket框架得到改进。
4.2 未来展望
目前,Brisket仍然是一个低于1.0.0版本的项目,团队正在积极朝着1.0.0版本发布努力。计划中的新功能和改进包括:
- 简化将大型Brisket应用拆分为更小捆绑包的过程。
- 重新架构服务器端渲染,以提高速度。
- 持续简化和优化API。
- 摆脱对jQuery的依赖。
- 为生成器、异步函数和模板字符串的到来做好准备。
以下是Brisket未来改进计划的流程图:
graph LR;
A[拆分应用捆绑包] --> B[重新架构服务器端渲染];
B --> C[简化和优化API];
C --> D[摆脱jQuery依赖];
D --> E[适应新特性];
5. Colony案例的总结与启示
Colony案例展示了在不使用Node.js的情况下构建同构应用的可行方案。通过选择合适的模板语言和设计统一的数据结构,团队成功地将传统服务器渲染的可索引网站与单页应用相结合。
- 模板语言的选择 :Handlebars作为一种无逻辑的模板语言,在C#和JavaScript中都有实现,使得前端和后端可以共享模板,提高了开发效率。
- 数据结构的设计 :统一的数据结构为应用状态的管理提供了清晰的方式,确保了前后端数据的一致性。
Colony的成功经验表明,不同技术栈可以通过合理的设计和选择,实现高效的同构应用开发,为开发者提供了一种新的思路和方法。
综上所述,Brisket框架和Colony案例都为同构应用的开发提供了有价值的参考和实践经验。无论是框架的设计理念还是实际案例的解决方案,都有助于开发者更好地应对同构应用开发中的挑战,构建出更加高效、灵活的应用程序。
超级会员免费看
11

被折叠的 条评论
为什么被折叠?



