开工福利|免费学 2200+ 精品线上课,企业成员人人可得! 了解详情
写点什么

Uber 开源 Fusion.js:一个基于插件架构的通用 Web 框架

  • 2018-08-13
  • 本文字数:2621 字

    阅读完需:约 9 分钟

Uber开源Fusion.js:一个基于插件架构的通用Web框架

可能很多人都不知道,Uber 其实开发了很多基于 Web 的应用程序,可能有数百个,而且这个数字还在不断增加中,它们中的大部分被用在公司内部,用于管理各种业务。

我们知道,Web 技术变化得很快,而最佳技术实践也在不断发展。为数百名 Web 工程师提供高质量的框架和功能,同时又要保持 Web 平台的动态特性,一直以来都是一个巨大的挑战。

为了应对这一挑战,Uber 的 Web 平台团队开发了 Fusion.js,一个开源的 Web 框架,用于简化 Web 开发,并构建出高性能的轻量级 Web 应用程序。

动机

随着 Web 最佳实践的发展,Uber 需要改造已有的单体 Web 框架,解决长达数年的技术债务所带来的挑战。我们还希望让工程师们能够继续使用他们喜欢的技术(例如 React 和 Redux),同时保持与 Uber 健康监控基础设施的兼容性。

具体来说,我们希望核心框架能够解决以下痛点:

  • 服务器端渲染、代码拆分和模块热加载所需的复杂配置和工具样板代码

  • 在涉及服务器端渲染的 React 应用程序时,缺乏用于实现和共享特性的良好抽象

  • 不同位置的代码紧密耦合而导致的脆弱性

  • 测试难度攀升

  • 单体框架​​缺乏灵活性

虽然现有的解决方案解决了其中的一些挑战,但我们发现,基于框架添加新库通常需要修改多个不相关的文件。例如,要让可进行服务器端渲染的应用程序支持 Redux, 通常需要在服务器相关的文件中添加代码,并在客户端添加类似的代码,还要向 HTML 模板中添加 hydration 代码,使用 React Provider 组件等。要集成 i18n 库或添加浏览器性能指标库也是一样。

很多特定于应用程序的代码可能会依赖用于管理副作用的库(例如用于日志记录或数据持久化的库),工程师很难在没有服务层抽象的帮助下以可测试的方式集成这些库。

我们既希望能够为与 Uber 现有库集成提供简单且经过实战考验的解决方案,也希望能够避免使用单体框架,从而保持捆绑包的小体积。

我们倾向于选择模块化方法的另一个原因是,我们必须明确指定依赖关系,这样可以更容易避免技术债务,如 God Object( https://en.wikipedia.org/wiki/God_object )、临时内部接口和紧密耦合。

Fusion.js 是我们努力的结晶。

谁应该使用 Fusion.js?

简单地说,Fusion.js 是一个 MIT 许可的 JavaScript 框架,支持 React 和 Redux 等流行库,并提供了很多现代特性,如模块热加载、数据感知服务器端渲染和捆绑拆分支持。

除了预配置的样板,Fusion.js 还提供了灵活的基于插件的架构。因此它非常适合用于现代单页应用程序以及依赖复杂服务层来满足各种质量要求的现代 Web 应用程序。

有关 Fusion.js 的更多信息,请查看项目文档。

基于插件的架构

Fusion.js 应用程序是通用的,也就是说它有一个单入口文件,并且可以在服务器和浏览器上重用代码。在通用的应用程序中,React 组件还可以获取数据并在服务器上渲染 HTML,从而可以利用浏览器的原生 HTML 解析器和避免 JavaScript DOM API 的开销来减少页面加载时间。

单入口架构使 Fusion.js 插件本身也具有通用性,插件开发人员可以将代码片段与代码所属的库放在一起,而不是与代码运行的环境放在一起。

Fusion.js 插件基于逻辑分组封装逻辑,而不是基于需要添加代码的位置

插件可以通过中间件访问 HTTP 请求生命周期,也可以访问 React 树,以便添加 Provider 组件。它们还可以初始化浏览器代码。

最后,由于这些特性,我们可以通过单行代码将库安装到应用程序中,无论库需要多少个不同的集成点。由于插件易于添加和删除,因此在重构时也很容易推断它们之间的耦合度、对包大小的影响以及其他代码质量属性。它们也可以初始化浏览器代码。

类型依赖注入

插件利用了依赖注入,这意味着它们可以将定义良好的 API 作为服务暴露给其他插件,并且在测试期间可以轻松地模拟插件的依赖项。当依赖关系负责与数据存储基础设施打交道或与可观察性(例如日志记录、分析和指标)相关时,这一点尤为重要。

复制代码
/*
这个例子实现了一个从 session 读取数据的端点。
Session 是通过依赖注入的方式提供的。
SessionToken 是一个标签 (用于确保类型安全)。
*/
// src/plugins/user.js
import {createPlugin} from 'fusion-core';
import {SessionToken} from 'fusion-tokens';
export default __NODE__ && createPlugin({
deps: {Session: SessionToken},
middleware({Session}) {
return async (ctx, next) => {
if (ctx.path === '/api/user') {
ctx.body = JSON.parse(await Session.from(ctx).get('user'));
}
return next();
}
}
});

还可以借助 Flow.js 来确保依赖之间的静态类型安全,如下所示:

直接在代码编辑器中显示错误有助于在代码运行之前捕获错误

中间件管理

几年前就存在这样的一个挑战,流行的HTTP 服务器库Express 有一个API 让复杂的响应转换变得难以封装和测试。在Uber 以前的架构中,应用程序开发人员经常需要采用临时包含Express 请求/ 响应对象的特定补丁。自然而然地,因为子系统对时间要求的高度耦合,测试变得极其困难。

在开始设计Fusion.js 时,我们就一直关注这个问题。经过大量调研,我们决定使用Koa( https://koajs.com ),它提供了基于上下文的 API,对单元测试非常友好,并为请求生命周期管理提供了一个基于下游和上游概念的轻量级抽象。

事实证明,采用 Koa 是一个正确的设计决策。

Koa 中间件为 React Provider 组件提供逻辑集成点,下游 / 上游抽象与 React 服务器渲染上下文的生命周期完美匹配。网络副作用与应用程序逻辑分离,从而提高了可测性。

Fusion.js 的依赖注入和图解析机制解决了困扰我们已久的 God Object 和操作顺序问题。

Fusion.js 核心将网络副作用与应用程序状态隔离开来,并利用 Koa 和 DI 来实现子系统之间的松散耦合

可测性

在过去的几年里,JavaScript 生态系统中出现了大量高质量的测试工具,并提高了对测试技术的认识。

除了支持 Jest、Enzyme 和 Puppeteer 等现代测试工具外,Fusion.js 还为开发人员提供了测试插件的工具。fusion-test-utils 包允可用于模拟服务器本身,从而可以在插件和各种桩的组合上快速运行集成测试。

前行之路

在 Uber 内部,已有 60 多个项目代码库在使用 Fusion.js。我们预计这个数字会继续增加,因为新的 Web 项目也在不断创建,同时旧项目被自动迁移到 Fusion.js。因此,框架级别的改进应该能够显著改善这些项目的软件质量基准。

我们的路线图包括添加更多的性能优化和面向测试的工具,以及更好的 Flow 支持。

项目地址: https://github.com/fusionjs

查看英文原文: https://eng.uber.com/fusionjs/

感谢覃云对本文的审校。

2018-08-13 19:003809
用户头像

发布了 731 篇内容, 共 456.2 次阅读, 收获喜欢 2003 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

自主可控,WorkPlus助力企业业务与生态的连接

BeeWorks

国产芯片破晓时,信创行业正扬帆

脑极体

芯片

鲨海狂潮,存力崛起

白洞计划

存储

安全攻防实战丨如何预防利用中间人攻击进行小程序刷分

华为云开发者联盟

网络安全 安全 华为云 系统安全 华为云开发者联盟

18万奖金!开放原子开源大赛OpenCloudOS赛题征集开启

开放原子开源基金会

开源 大赛

今年双十一,00后在直播间当“捧哏”,月入8000

自象限

借助文心大模型4.0轻松搞定统计报表

阿Q说代码

文心大模型 文心4.0 统计报表

2023平台工程崭露头角,AI 带来新机遇与挑战

SEAL安全

AI 平台工程 企业号10月PK榜

3种方法,用Java找出两个List中的重复元素

华为云开发者联盟

Java 开发 华为云 华为云开发者联盟

Mac系统设置维护工具TinkerTool System最新激活版

mac大玩家j

系统维护 Mac软件 系统维护软件

故障解析丨Clone节点导致主从故障

GreatSQL

After Effects 2024 for Mac(视频特效制作软件) v24.0.1.2完整激活版

mac

苹果mac Windows软件 视频特效软件 After Effects 2024 AE2024

产品研发团队协作神器!10款提效工具大盘点!

彭宏豪95

产品经理 团队协作 开发工具 产品研发 在线白板

五矿期货:悦数图数据库在金融期货行业的应用与实践探索

悦数图数据库

数据库 图数据库

Linux的命令基本格式

芯动大师

Vuepress 三分钟搭建一个精美的文档或博客

凌览

Vue 博客 vuepress

语雀故障与反思,随便再领半年会员!

王磊

显卡又又又涨价了!那就用青椒云吧!

青椒云云电脑

青椒云

文心一言 VS 讯飞星火 VS chatgpt (120)-- 算法导论10.3 5题

福大大架构师每日一题

福大大架构师每日一题

可重入锁ReentrantLock在性能测试常见用法

FunTester

Redis ReHash原理

宁静知行者

redis Redis 核心技术与实战

不被大厂“卡脖子”,选择WorkPlus拥抱生态伙伴时代

BeeWorks

Mac电脑专业思维导图软件 ConceptDraw MINDMAP最新激活版

胖墩儿不胖y

Mac软件 思维导图软件

WorkPlus专注私有化部署,为企业安全打造超级沟通协作APP

BeeWorks

业务出海、高效传输、动态加速,尽在云栖大会「CDN与边缘计算」专场

阿里云CloudImagine

云计算 云栖大会 边缘云

英伟达4090显卡全面下架,有哪些替代方案?

青椒云云电脑

青椒云

用Python发一个优雅的朋友圈,1行代码搞定

程序员晚枫

Python 微信 图片 朋友圈

【iOS逆向与安全】原生程序与WebView交互

小陈

逆向 iOS逆向 ios安全 逆向分析 逆向技术

Uber开源Fusion.js:一个基于插件架构的通用Web框架_Web框架_Uber_InfoQ精选文章