使用Fusion创建自定义插件。js, Uber的开源Web框架

0
使用Fusion创建自定义插件。js, Uber的开源Web框架

插件是的核心元素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 && yarn dev

这将在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应用程序感兴趣,可以考虑申请一个角色在我们的团队!

评论

没有帖子显示