插件是的核心元素Fusion.js, Uber的开源通用web框架及其架构。插件可以用来封装函数,这些函数在应用程序的不同部分中重用。在插件中封装的函数的例子有日志记录、翻译、库的实现和与数据源的集成。
Fusion提供了许多官方插件。它们允许开发人员无需编写自己的插件就可以构建复杂的应用程序。不过,该框架还允许开发人员构建自己的插件。在本文中,我们提供了一个如何使用Fusion.js创建自定义插件的例子。
插件的概念
js应用程序是通用的,这意味着它们只有一个入口点。js插件共享这种架构,使得用一行代码就可以把库安装到应用程序中。这是通过依赖注入实现的。
依赖注入
对于许多基于javascript的后端框架来说,依赖注入并不是一个内置概念,即使是,实现也并不总是理想的。由于这个原因,开发人员经常犹豫是否使用依赖项注入,如果必须使用第三方库来管理依赖项的话,情况就更糟了。
与传统的基于javascript的插件不同,依赖注入是Fusion.js插件的重要组成部分,插件可以将定义良好的API作为服务公开给其他插件。这意味着可以创建插件,并很容易地在需要的地方跨应用程序注入插件。
一些核聚变的好处。js的依赖注入功能包括:
- 创建一个插件并在需要的地方注入它
- 轻松地在应用程序之间共享代码
- 分离中的应用
- 使用可测试插件增加测试覆盖率
在需要的地方创建并注入
管理依赖项(甚至在大型应用程序中)的一种常见方法是将它们添加到应用程序的顶部,并在构建中包含所有内容。js有一个不同的方法:依赖关系被注入到需要的地方,这意味着只需要包含在浏览器包中。
依赖注入不仅仅是Fusion的核心特性。通过允许它们将定义良好的api作为服务公开,这些服务可以被注入到其他插件中,它加强了插件概念。这个功能使得解耦组件或特性,甚至共享代码变得更加容易。
甚至将简单的特性封装为插件也是有用的。以日志为例。日志通常在应用程序的所有部分都很有用,使用日志服务插件,应用程序可以在需要的地方轻松实现日志特性。使用日志插件也使代码更容易维护,因为所有日志代码都维护在一个位置。没有必要在所有实现日志的地方都进行更改。
测试很容易
js架构师从早期设计阶段就一直致力于优化可测试性。在像Uber这样的架构中,由于子系统和操作顺序的高度耦合,测试是一个挑战,提高可测试性是一个需求。
js支持现代测试工具,如Jest、Puppeteer和Enzyme。除了支持第三方测试工具外,Fusion.js还提供了fusion-test-utils,用于测试插件的工具。该工具可以模拟服务器本身,使快速运行集成测试成为可能。
通过带有依赖项的Fusion.js插件公开的服务可以通过调用服务进行单元测试,并将所需的依赖项作为参数传递进来。(查看如何对插件进行单元测试的示例。)
样例应用程序
为了演示如何创建和使用插件,我们构建了一个小的示例应用程序。在我们的用例中,这个示例应用程序将温度从华氏温度转换为摄氏温度,反之亦然。
应用程序的功能由两个插件处理。有一个插件公开温度转换服务,将温度作为输入并返回转换后的温度。该插件的中间件将在浏览器中呈现两个方向的温度转换结果。第二个插件将从第一个插件注入转换服务来进行单向转换,从而演示依赖注入如何在Fusion.js中工作。
温度转换应用程序的步骤是:
- 创建一个Fusion.js应用程序
- 创建转换器插件
- 创建用于呈现结果的组件
- 注册插件
- 通过注入一个新的插件来重用插件
创建Fusion.js应用程序
在使用时,创建Fusion.js应用程序非常简单纱创建。如果您以前已经这样做过,您可以跳到下一个步骤。如果你是核聚变的新手。js,这是一切开始的地方。
在终端中,运行以下命令:
| yarn create fusion-app |
这个命令将创建一个样板应用程序,其中包含运行包含的演示页面所需的所有文件和目录。在运行纱创建,运行这个命令:
| cd |
这将在http://localhost:3000上提供Fusion.js演示页面。
src目录下的文件结构是这样的:
| 。 ├──页面 │├──home.js │└──pageNotFound.js ├──main.js └──root.js |
这个例子不需要默认的演示页面,所以home.js文件可以被删除,主页的路径也可以从root.js文件中删除。它们也可以保留在项目中。
创建转换插件
转换器服务在转换器插件中创建,温度转换的结果在浏览器中呈现。
转换器插件是创建的createPlugin ()功能:
| / / src /插件/ converters.js 进口{createPlugin}从“fusion-core”; 出口默认的createPlugin ({ deps: {}, 提供(){}, 中间件(){} }); |
插件将不依赖于其他插件,所以deps可以删除。转换服务将在中创建提供了,组件将被渲染中间件。
转换服务
该插件包含两个服务,一个用于将温度从摄氏温度转换为华氏温度,另一个用于将华氏温度转换为摄氏温度。两个服务都接受一个参数,即温度,并且都返回转换后的温度。
温度转换函数被插入插件的提供()功能:
| 提供(){ 返回{ convertToCelsius(临时){ 常量摄氏度= (temp -32) *5/9; 返回摄氏度; }, convertToFahrenheit(临时){ 常量华氏温度= (temp * (5/9) +32; 返回氏度; } }; } |
渲染组件
最后,通过包装组件树,将转换器API提供给组件树ctx.element在上下文提供程序中。
的ctx.element保存应用程序根元素,并基于应用程序构造函数进行设置。插件可以通过包装上下文提供程序来添加上下文提供程序ctx.element在一个中间件。但是,我们必须首先检查元素是否存在,因为它只存在于映射到页面呈现的请求中。例如,它不存在于静态资产和POST请求的请求中。
| 中间件({},自我){ 返回(ctx, next) => { 如果(ctx.element) { ctx.element=( <ConverterProvider价值={自我}> {ctx.element} ConverterProvider> ); } 返回next (); }; } |
中间件的第一个参数传递了注入的依赖项,但由于在这个应用程序中不需要这样做,因此依赖项对象为空。第二个参数是插件提供的服务。在本例中,它是转换器API。
这是完整的转换器插件:
| / / src /插件/ converters.js 进口反应从”反应”; 进口{createPlugin, html}从”fusion-core”; 常量{Provider, Consumer} = response . createcontext ()假); 出口{消费者作为ConverterConsumer}; 出口默认的createPlugin ({ 提供(){ 返回{ convertToCelsius(临时){ 常量摄氏度= (temp -32) *5/9; 返回摄氏度; }, convertToFahrenheit(临时){ 常量华氏温度= (temp * (9/5) +32; 返回氏度; } }; }, 中间件(deps, converter) { 返回(ctx, next) => { 如果(ctx.element) { ctx.element=( <ConverterProvider价值={转换器}> {ctx.element} </ ConverterProvider> ); } 返回next (); } } }); |
创建组件
该组件包含用于创建要在浏览器中呈现的内容的所有逻辑。对于这个简单的应用程序,目标是输出温度转换的结果。浏览器中的结果应该是这样的:
25华氏度换算成摄氏温度是零下4度
25°c转换成华氏温度就是77°
温度转换由转换器插件中的服务处理,组件允许服务通过。在这个应用程序中,温度只是作为一个常数提供的。在真实的应用程序中,温度当然可以由用户、后端或远程服务提供。
该组件使用React Context,这是Fusion.js中呈现结果的一种常见方法。除了创建要呈现的内容的逻辑之外,还使用组件代码创建React上下文。
| / / src /组件/ converters.js 进口反应从“反应”; 进口{消费者}从“. . /插件/转换器”; 出口函数ConverterComponent(){ 常量温度=25; 返回( <消费者> {(值)= > ( < div > < p > {温度}度;华氏温度转换成摄氏温度 {Math.round (value.convertToCelsius(温度)}度; < / p > < p > {温度}度;摄氏度转换成华氏度 {Math.round (value.convertToFahrenheit(温度)}度; < / p > < / div > )} 消费者> < / ); } |
转换后的温度可以返回十进制数字,并可以四舍五入为整数Math.round (),如上面的代码所示。组件ConverterComponent导出,并将提供程序导出为ConverterProvider。
注册插件
最后一步是注册插件。这是在main.js中完成的文件:
| / / src / main.js 进口反应从“反应”; 进口应用程序从“fusion-react”; 进口ConverterPlugin从“/插件/ converter.js。”; 进口根从”。/ ConverterComponent '; 出口默认的()= > { 常量应用=新应用程序(<根/ >); app.register (ConverterPlugin); 返回应用程序; }; |
结果
现在应用程序完成了,并通过运行应用程序纱线开发,应用程序将在本地主机的默认端口3000上被服务:

重用转换服务
中间件插件中的转换服务向其他插件公开,并且可以轻松地作为依赖注入到其他插件中。到目前为止,转换服务还没有在应用程序的其他插件中使用,但是让我们创建一个小插件来说明依赖注入如何工作。
该插件注入转换服务,并添加两个端点:
- /转换/摄氏
- /转换/华氏温度
当转换器插件将呈现两个转换方向的结果时,这两个端点将只呈现一个方向的结果:摄氏到华氏或华氏到摄氏。温度是通过使用查询参数提供的度。
创建令牌
为了将转换器插件作为依赖注入到新插件中,必须为转换器插件脚本创建一个令牌并导出:
| / / src /插件/ converters.js 进口{createPlugin, createToken}从“fusion-core”; … 出口常量ConverterToken = createToken (“ConverterToken”); |
令牌必须在主文件中注册,但这将在最后一步中完成。所以现在,假设令牌是可用的。
创建端点插件
转换器令牌作为依赖性注入到新插件中,现在转换服务可以在新插件中使用。(有关端点如何工作的更多信息,请查看我们的文档在这个问题上)。
| / / src /插件/ endpoints.js 进口反应从“反应”; 进口{createPlugin}从“fusion-core”; 进口{ConverterToken}从”。/转换器”; 出口默认的createPlugin ({ deps:{转换器:ConverterToken}, 中间件({转换器}){ 返回异步(ctx, next) => { 等待next (); 如果(ctx.path.startsWith (“摄氏/转换/”)) { 常量tempF = 数学.round (converter.convertToFahrenheit (ctx.query.degrees)); ctx。body = ctx.query.degrees +度;摄氏温度转换为 华氏温度是”+ tempF +度;’; }其他的如果(ctx.path.startsWith (/转换/华氏温度的)) { 常量tempC = 数学.round (converter.convertToCelsius (ctx.query.degrees)); ctx。body = ctx.query.degrees +度;华氏温度转换成 摄氏温度是+ tempC +度;’; } } } }); |
注册端点和转换器令牌
作为最后一步,注册端点插件,并注册转换器令牌:
| / / src / main.js 进口反应从“反应”; 进口应用程序从“fusion-react”; 进口转换器,{ConverterToken}从“/插件/ converters.js。”; 进口端点从“/插件/ endpoints.js。”; 常量根=< div / >; 出口默认的()= > { 常量应用=新应用程序(根); app.register (ConverterToken转换器); app.register(端点); 返回应用程序; }; |
结果
现在可以只在一个方向上转换温度,并渲染结果。对于摄氏温度到华氏温度的转换,使用温度作为查询参数调用端点,/转换/ 30摄氏度=:

总结
插件是融合中封装服务和中间件的好方法。本文中的简单应用程序演示了它。插件可以注入到其他插件中,公开的插件服务可以在整个应用程序中使用。
本文仅介绍了插件的基本用法,展示了如何创建服务插件、将插件作为依赖注入到另一个插件中、在插件中创建端点以及从插件中呈现结果。想了解更多关于Fusion.js插件的信息,请访问官方网站控件中的更多代码示例开始和融合API文档部分。
对这个开源框架感到好奇吗?尝试Fusion.js为自己!
如果您对构建大型web应用程序感兴趣,可以考虑申请一个角色在我们的团队!






