feature功能_利用feature-u V1释放基于功能的JS开发的强大功能

海叶秋
2023-12-01

feature功能

This article is an introduction to a new JS library called feature-u, that facilitates feature-based development in your React project.

本文是对新的JS库(称为feature-u )的介绍,该库促进了React项目中基于功能的开发

Note: On 8/14/2018 feature-u V1 was released, that re-designed Cross Feature Communication to include UI Composition as a core offering. This article covers the V1 release. The first article, based on feature-u V0, can be found here. We are very excited about this update because it promotes one solution for all feature collaboration!

注意 :在8/14/2018上发布了功能-u V1 ,该功能重新设计了跨功能通信,以将UI合成作为核心产品纳入其中。 本文介绍了V1版本。 第一篇基于feature-u V0的文章可以在这里找到。 我们对此更新感到非常兴奋,因为它为所有功能协作提供了一种解决方案

Most developers would agree that organizing your project by feature is much preferred over type-based patterns. Because application domains grow in the real world, project organization by type simply doesn’t scale, it just becomes unmanageable!

大多数开发人员都同意,按功能组织项目比基于类型的模式更为可取。 由于应用程序领域在现实世界中不断增长按类型组织的项目组织根本无法扩展只会变得难以管理

There are a number of good articles that discuss this topic with insight on feature-based design and structure (see: References below). However when it comes to the implementation, you are pretty much left to fend for yourself.

有很多很好的文章讨论了这个主题,并对基于功能的设计和结构有深入的了解(请参阅:下面的参考资料 )。 但是,当涉及到实现时,您几乎无所事事。

feature-u is a utility library that manages and streamlines this process. It automates the mundane details of managing features and helps to promote features that are truly plug-and-play.

feature-u是一个实用程序库,用于管理和简化此过程。 它可以自动化管理功能的日常细节,并有助于提升真正的即插即用功能。

This article provides a foundation of feature-u concepts and terminology, building insight into how you can promote individual plug-and-play features within your project. It makes the case for why feature-u was developed and gives you a better understanding of it’s benefits.

本文提供了功能u概念和术语的基础,深入了解了如何在项目中推广单个即插即用功能。 这说明了为什么开发了feature-u的原因,并使您更好地了解它的好处。

Check out the full docs, source, and npm package.

查看完整的docssourcenpm软件包

feature-u opens new doors into the exciting world of feature-based development. It frees you up to focus your attention on the “business end” of your features!

feature-u打开了令人兴奋的基于功能的开发世界的新门。 它使您腾出精力专注于功能的“业务端”

乍看上去 (At a Glance)

For your convenience, this Table of Contents (TOC) links directly to each section. Also note that each section title links back to the TOC.

为了您的方便,此目录 (TOC)直接链接到每个部分。 还要注意,每个部分的标题都链接回目录

Feature Based Development  Segregating Features  Feature Goals    Feature Runtime Consolidation    Feature CollaborationThe feature-u Solution  launchApp()  Feature Object  aspects  Running the App    App Initialization    Framework Configuration    Launching Your Application  Cross Feature Communication  Feature Based UI Composition    Resource Contracts  Feature EnablementIn SummaryBenefitsReferences

Please help me get the word out on feature-u. Your claps determine the distribution/promotion of this article. If you think feature-u has potential, please give this article multiple claps :-)

帮助我 说出 功能-u 您的掌声决定了本文的分发/宣传。 如果您认为feature-u有潜力,请给本文多次鼓掌:-)

基于功能的开发 (Feature Based Development)

At a 30,000 ft view, feature-based development (as in most software) is all about dissecting hard problems into smaller pieces. Even when I started my career (back in the 70's), this was a prominent quote:

在30,000英尺的视野中,基于功能的开发(与大多数软件一样)就是将棘手的问题分解为较小的部分。 即使我开始了自己的职业生涯(上世纪70年代) ,这仍然是一个引人注目的报价:

“All problems in computer science can be solved by another level of indirection.” David Wheeler

“计算机科学中的所有问题都可以通过另一层间接解决。” 戴维·惠勒

By breaking up your application into features, each feature can focus on a more specific and isolated set of tasks. In some ways you can think of a feature as a “mini application”!

通过将您的应用程序分解为功能,每个功能可以专注于一组更具体和更孤立的任务。 在某些方面,您可以将功能视为“小型应用程序”

There are many design considerations in defining your feature boundaries. You can find several articles on this topic that provide insight on feature-based design.

定义要素边界时有许多设计注意事项。 您可以找到有关此主题的几篇文章,以深入了解基于功能的设计。

For the most part, these considerations are part of the design of each individual project. While feature-u does not dictate overall design considerations, it does facilitate good feature-based principles (such as encapsulation). This will be the focus of this article.

在大多数情况下,这些考虑都是每个单独项目设计的一部分。 虽然功能-u并未决定总体设计考虑因素,但它确实促进了基于功能的良好原则(例如封装)。 这将是本文的重点

隔离功能 (Segregating Features)

If you are like me, when you think about feature-based development, the first thing that comes to mind is to isolate your code into feature directories.

如果您像我一样,在考虑基于功能的开发时,首先想到的是将代码隔离到功能目录中。

In doing this your code is organized by what it accomplishes (i.e. features), rather than what it is (i.e. components, routes, logic, actions, reducers, selectors, etc.).

在执行此操作时,代码是根据其完成的功能(即功能)而不是其内容(即组件,路线,逻辑,操作,缩减器,选择器等)进行组织的。

By segregating your features into individual directories, there is a semblance of isolation.

通过将要素分离到各个目录中,可以实现一定程度的隔离。

功能目标 (Feature Goals)

Our goal is to encapsulate each feature in such a way as to make them truly plug-and-play. But how is this accomplished?

我们的目标是封装每种功能 ,以使其真正实现即插即用但是,这是如何完成的呢?

The directory structure is just a start. There are several hurdles that must be overcome to realize our goal …

目录结构只是一个开始。 要实现我们的目标,必须克服几个障碍 ……

  • How do we encapsulate and isolate our features, while still allowing them to collaborate with one another?

    我们如何封装和隔离我们的功能,同时又允许它们彼此协作?
  • How can selected features introduce start-up initialization (even injecting utility at the root DOM), without relying on some external startup process?

    所选功能如何在不依赖某些外部启动过程的情况下,启动启动初始化(甚至在根DOM处注入工具)?
  • How can feature-based UI Composition be accomplished in an isolated and autonomous way?

    如何基于功能的UI组合以孤立的自主方式完成?
  • How do we configure our chosen frameworks now that our code is so spread out?

    既然我们的代码是如此分散,我们如何配置我们选择的框架?
  • How do we enable/disable selected features which are either optional, or require a license upgrade?

    我们如何启用/禁用可选功能,这些功能要么是可选的,要么需要许可证升级?

In short, how do we achieve a running application from these isolated features?

简而言之 ,我们如何从这些孤立的功能中获得一个正在运行的应用程序?

When you boil it all down, there are two overriding characteristics that must be accomplished to achieve our goals:

当您全部煮沸时,必须实现两个首要特征才能实现我们的目标:

  1. Feature Runtime Consolidation: pulling our features back together into one running application

    Feature Runtime Consolidation将我们的功能重新组合到一个正在运行的应用程序中

  2. Feature Collaboration: provide a mechanism by which our features can interact with one another

    Feature Collaboration提供一种机制,通过这些机制我们的功能可以相互交互

As it turns out, everything else is a byproduct of these two artifacts. Let’s take a closer look at each of these items.

事实证明, 其他所有东西都是这两个工件的副产品 。 让我们仔细看看这些项目。

功能运行时合并 (Feature Runtime Consolidation)

Now that we have isolated our features into separate entities, how do we bring them back together so they run as one application? We must be able to pull and configure various aspects of our individual features, and “launch” them as a single homogeneous running application.

现在我们已经将功能隔离到单独的实体中,我们如何将它们重新组合在一起以使它们作为一个应用程序运行? 我们必须能够提取和配置各个功能的各个方面,并将它们作为单个同类运行的应用程序“启动”。

This concern can be further divided into two sub-concerns:

此问题可以进一步分为两个子问题:

  • App Initialization

    App Initialization

    Some features may require certain startup initialization. As an example, a feature that encapsulates some DB abstraction will rely on a run-time setup of a DB service.

    某些功能可能需要某些启动初始化。 例如,封装一些数据库抽象的功能将依赖于数据库服务的运行时设置。

    Certainly we don’t want to rely on some global app logic to accomplish this

    当然,我们不想依靠某些全局应用逻辑来完成此任务

    (once again, we want our features to be encapsulated and self-sufficient).

    (再一次,我们希望我们的功能被封装并且自给自足)

  • Framework Configuration

    Framework Configuration

    If your application relies on other frameworks, chances are there are resources contained within each feature that must be accumulated and fed into the framework configuration process.

    如果您的应用程序依赖于其他框架,则每个功能中包含的资源很可能必须累积并输入到框架配置过程中。

    How is this accomplished?

    这是如何完成的?

功能协作 (Feature Collaboration)

The second characteristic (mentioned above) is Feature Collaborationproviding a mechanism by which our features can interact with one another.

第二个特征(如上所述)是特征协作 - 提供一种机制,通过这些机制我们的特征可以相互交互

A best practice of feature-based development (to the extent possible) is to treat each feature as an isolated implementation. Most aspects of a feature are internal to that feature’s implementation (for example, actions are typically created and consumed exclusively by logic/reducers/components that are internal to that feature).

基于功能的开发的最佳实践 (在可能的范围内)将每个功能视为独立的实现 。 功能的大多数方面都在该功能的实现内部(例如,动作通常是由该功能内部的逻辑/归约器/组件专门创建和使用的)

From this perspective, you can think of each feature as its own isolated mini application.

从这个角度来看,您可以将每个功能都视为自己独立的微型应用程序

With that said, however, we know that no man is an island! Any given feature ultimately exists as part of a larger application. There are cases where a feature needs to promote a limited subset of its aspects to other features. For example, a feature may need to:

话虽如此,我们知道 没有人是一个岛屿 ! 任何给定的功能最终都会作为大型应用程序的一部分存在。 在某些情况下,某个功能需要将其各个方面的有限子集提升为其他功能。 例如,功能可能需要:

  • be knowledgeable of some external state (via a selector)

    了解一些外部状态(通过选择器)
  • emit or monitor actions of other features

    发出或监视其他功能的动作
  • consolidate component resources from other features — as in UI Composition

    整合其他功能中的组件资源-如UI组成

  • invoke the API of other features

    调用其他功能的API
  • etc. etc. etc.

    等等等等

These items form the basis of why Cross Feature Communication and Feature Based UI Composition are needed.

这些项目构成了为什么需要Cross Feature CommunicationFeature Based UI Composition

To complicate matters, as a general rule, JS imports should NOT cross feature boundaries. The reason being that this cross-communication should be limited to public access points — helping to facilitate true plug-and-play.

为了使事情复杂化,通常, JS导入不应跨越要素边界 。 原因是这种交叉通信应仅限于公共访问点 ,从而有助于真正的即插即用

Given all this then, how is Cross Feature Communication achieved in a way that doesn’t break encapsulation?

鉴于所有这些, 如何 以不破坏封装的方式 实现跨功能通信

Features need a way to promote their Public Interface to other features, and consume other feature’s Public Assets.

功能需要一种将其公共界面升级为其他功能并消耗其他功能的公共资产的方法

功能-u解决方案 (The feature-u Solution)

Let’s take a look at the solution feature-u provides for all of these goals. The following sections will build feature-u concepts incrementally.

让我们看一下为所有这些目标提供的解决方案功能 。 以下各节将逐步构建feature-u概念。

launchApp() (launchApp())

launchApp() is an essential utility in feature-u. It is an agent, working on your behalf, which provides the foundation that accomplishes all the goals of feature-u! It facilitates both Feature Runtime Consolidation and Feature Collaboration.

launchApp()feature-u中必不可少的工具。 它是代表您工作的代理,它为完成 feature-u的 所有目标提供了基础。 它促进了Feature Runtime ConsolidationFeature Collaboration

With this utility, your mainline startup process is extremely simple … it merely invokes launchApp(), and you are done!

使用此实用程序, 您的主线启动过程非常简单 ……它只调用launchApp() ,您就完成了!

The launchApp() function actually starts your application running, employing various hooks that drive BOTH App Initialization and Framework Configuration!

launchApp()函数实际上使用各种驱动程序初始化框架配置的钩子来启动您的应用程序运行!

You can find launchApp() examples in the Usage section, and Launching Your Application.

您可以在“ Usage部分和“ Launching Your Application找到launchApp()示例。

How does this work? What are the bindings to launchApp()? ... let's delve a bit deeper…

这是如何运作的? 什么是launchApp()的绑定 ? ... 让我们更深入地研究...

特征对象 (Feature Object)

To accomplish this, each feature promotes a Feature object (using createFeature()), that catalogs aspects of interest to feature-u.

为此,每个功能都会提升一个Feature对象(使用createFeature() ) ,该对象将feature-u感兴趣的方面分类。

This is the primary input to launchApp().

这是launchApp()的主要输入。

方面 (aspects)

In feature-u, “aspect” (little “a”) is a generalized term used to refer to the various ingredients that (when combined) constitute your application. Aspects can take on many different forms: UI ComponentsRoutesState Management(actions, reducers, selectors)Business LogicStartup Initialization Codeetc. etc. etc.

功能u中 ,“方面” (小写“ a”)是一个广义术语,用于指代(组合时)构成您的应用程序的各种成分。 方面可以采取许多不同的形式: UI组件路由状态管理 (动作,缩减器,选择器)业务逻辑启动初始化代码等等等。

Not all aspects are of interest to feature-uonly those that are needed to setup and launch the application … all others are considered an internal implementation detail of the feature. As an example, consider the Redux state manager: while it uses actions, reducers, and selectors … only reducers are needed to setup and configure Redux.

并非所有方面都与功能有关-仅是那些设置和启动应用程序所需的方面 ...所有其他方面都被视为该功能的内部实现细节。 举个例子,考虑一下Redux状态管理器:当它使用动作,缩减器和选择器时……仅需要缩减器即可设置和配置Redux。

The Feature object is merely a lightweight container that holds aspects of interest to feature-u. These aspects can either be Built-In aspects (from core feature-u), or Extendable aspects (from plugin extensions).

Feature对象只是一个轻量级容器,其中包含feature-u感兴趣的方面。 这些方面可以是Built-In aspects (来自核心功能-u ) ,也可以是Extendable aspects (来自插件扩展)

运行应用 (Running the App)

Let’s see how launchApp() accommodates the two sub-goals of running the app:

让我们看看launchApp()如何容纳运行应用程序的两个子目标:

应用初始化 (App Initialization)

Because launchApp() is in control of starting the app, it can introduce Application Life Cycle Hooks.

因为launchApp()可以控制启动应用程序,所以它可以引入Application Life Cycle Hooks

This allows each feature to perform app-specific initialization, and even inject components into the root of the app.

这允许每个功能执行应用程序特定的初始化,甚至将组件注入到应用程序的根目录中。

There are two hooks:

有两个钩子:

  1. Feature.appWillStart() - invoked one time at app startup time

    Feature.appWillStart() -在应用启动时调用一次

  2. Feature.appDidStart() - invoked one time immediately after app has started

    Feature.appDidStart() -应用启动后立即调用一次

Application Life Cycle Hooks greatly simplify your app's mainline startup process, because initialization specific to a given feature can be encapsulated in that feature.

Application Life Cycle Hooks 极大地简化应用程序的主线启动过程 ,因为特定于给定功能的初始化可以封装在该功能中

框架配置 (Framework Configuration)

A fundamental goal of feature-u is to automatically configure the framework(s) used in your run-time-stack (by accumulating the necessary resources across all your features). This greatly reduces the boilerplate code within your app.

feature-u的基本目标是自动配置运行时堆栈中使用的框架 (通过在所有功能中累积必要的资源) 。 这大大减少了应用程序中的样板代码。

How can this be accomplished when there are so many frameworks out there … and every project uses a different mix?

当有这么多框架……而每个项目使用不同的组合时,如何实现呢?

feature-u is extendable! It operates in an open plugable architecture where Extendable Aspects integrate feature-u to other frameworks, matching your specific run-time stack. This is good, because not everyone uses the same frameworks!

功能-u是可扩展的! 它在开放式可插拔体系结构中运行,其中可扩展方面feature-u与其他框架集成在一起,从而匹配您的特定运行时堆栈。 这很好, 因为不是每个人都使用相同的框架

Extendable Aspects can be found in external NPM packages (the normal case), or you can create your own using createAspect() (a more advanced topic).

可扩展方面可以在外部NPM包中找到(通常情况下) ,也可以使用createAspect()创建自己的createAspect() 更高级的主题)

The Aspect object contains a series of Aspect Life Cycle Hooks that are invoked under the control of feature-u(launchApp()). In general, an Aspect's responsibility is to:

Aspect对象包含一系列在Feature-u ( launchApp() )控制下调用的Aspect Life Cycle Hooks 。 通常,Aspect的责任是:

  • accumulate AspectContent across all features

    在所有功能上累积AspectContent

  • perform some desired setup and configuration

    执行一些所需的设置和配置
  • expose it’s functionality in some way (typically a framework integration)

    以某种方式(通常是框架集成)公开其功能

An Aspect automatically extends the Feature object by allowing it's AspectContent to be "cataloged" in the Feature using Aspect.name as it's key. In the diagram above, you can see that

一个Aspect自动扩展Feature通过允许它的对象AspectContent“编目”中的Feature使用Aspect.name作为它的关键。 在上图中,您可以看到

  • the reducerAspect (Aspect.name: 'reducer') permits a Feature.reducer: reducerContent construct

    reducerAspect ( Aspect.name: 'reducer' )允许Feature.reducer: reducerContent构造

  • and the logicAspect (Aspect.name: 'logic') permits a Feature.logic: logicContent construct

    logicAspect ( Aspect.name: 'logic' )允许Feature.logic: logicContent构造

It is important to understand that the interface to your chosen frameworks is not altered in any way. You use them the same way you always have (just within your feature boundary). feature-u merely provides a well-defined organizational layer, where the frameworks are automatically setup and configured by accumulating the necessary resources across all your features.

重要的是要了解,所选框架的接口不会以任何方式改变。 您可以像以前一样使用它们(仅在要素边界内)feature-u仅提供一个定义明确的组织层,在该层中,通过在所有功能上累积必要的资源来自动设置和配置框架。

启动您的应用程序 (Launching Your Application)

In feature-u, the application mainline is very simple and generic. There is no real app-specific code in it … not even any global initialization! That is because each feature can inject their own app-specific constructs!! The mainline merely accumulates the Aspects and Features, and starts the app by invoking launchApp():

功能u中,应用程序主线非常简单且通用。 其中没有真正的应用特定代码…… 甚至没有任何全局初始化 ! 那是因为每个功能都可以注入他们自己的应用程序特定的构造 ! 主线仅累积AspectsFeatures ,并通过调用launchApp()启动应用程序:

Here are some important points of interest (match the numbers to *n* in the code above):

这是一些重要的兴趣点 (将上面的代码中的*n*与数字匹配)

  1. the supplied Aspects (pulled from separate npm packages) reflect the frameworks of our run-time stack (in our example redux, redux-logic, and feature-router) and extend the acceptable Feature properties (Feature.reducer, Feature.logic, and Feature.route respectively) ... see: Extendable aspects

    提供的Aspects (从单独的npm软件包中拉出)反映了运行时堆栈的框架(在我们的示例reduxredux-logicfeature-router ),并扩展了可接受的Feature属性( Feature.reducerFeature.logic和分别为Feature.route ) ... 请参阅: Extendable aspects

  2. all of our app features are supplied (accumulated from the features/ directory)

    提供了我们所有的应用功能(从features/目录中累积)

  3. a registerRootAppElm() callback is used to catalog the supplied rootAppElm to the specific React platform in use. Because this registration is accomplished by your app-specific code, feature-u can operate in any of the React platforms, such as: react-web, react-native, and expo ... see: React Registration

    registerRootAppElm()回调用于将提供的rootAppElm入正在使用的特定React平台。 由于此注册是通过您的特定于应用的代码完成的,因此feature-u可以在任何React平台上运行,例如: react-webreact-nativeexpo ... 参见: React Registration

  4. as a bit of a preview, the return value of launchApp() is a Fassets object, which promotes the accumulated Public Face of all features, and is exported to provide Cross Feature Communication.

    作为预览launchApp()的返回值是一个Fassets object ,该Fassets object提升了所有功能的累积的Public Face,并被导出以提供Cross Feature Communication

跨功能交流 (Cross Feature Communication)

In support of Feature Collaboration that doesn’t break encapsulation, feature-u promotes feature-based resources through something called fassets (feature assets). This is how all Cross Feature Communication is accomplished. You can think of this as the Public Face of a feature.

为了支持不破坏封装Feature Collaborationfeature-u通过所谓的fassets (要素资产)促进基于要素的资源。 这就是完成所有跨功能通信的方式。 您可以将其视为功能的“ 公开面Kong ”。

SideBar: The term fassets is a play on words. While it is pronounced "facet" and is loosely related to this term, it is spelled fassets (i.e. feature assets).

边栏 :术语“ fassets是文字游戏。 虽然它的发音是“ facet”, 并且与该术语有松散的关系 ,但它却拼写成收藏(即要素资产)。

A feature can expose whatever it deems necessary through the built-in Feature.fassets aspect). There is no real constraint on this resource. It is truly open.

功能可以通过内置的Feature.fassets aspect公开它认为必要的任何内容。 此资源没有实际限制。 它是真正开放的。

The fassets aspect has a define directive where resources are cataloged.

fassets aspect有一个define指令,其中对资源进行了分类。

Here is a simple example of how fassets are defined:

这是一个关于如何定义fassets的简单示例:

feature-u accumulates fassets from all active features, and promotes them through the Fassets object (emitted from launchApp()).

feature-u从所有活动功能中累积fassets ,并通过Fassets object (从launchApp()发出launchApp()将其Fassets object

SideBar: There are several ways to obtain access the Fassets object (see Obtaining fassets object).

边栏 :有几种方法可以访问Fassets object (请参阅Obtaining fassets object )

To reference a fassets resource, simply dereference it as any other object reference. There is also a Fassets.get()method that can be supplied Wildcards, returning an array of resources.

要引用fassets资源,只需将其取消引用为任何其他对象引用即可。 还有一个Fassets.get()方法可以提供Wildcards ,返回一个资源数组。

This is an example of a push philosophy. Here the supplier is is simply publicly promoting a resource for other features to use (take it or leave it). The supplier is merely saying: “this is my Public Face”.

这是推式哲学的一个例子。 在这里,供应商只是在公开地宣传一种资源以供其他功能使用(使用或保留它) 。 供应商只是在说: “这是我的公开面Kong”

You can find more information about this topic in Cross Feature Communication.

您可以在“ Cross Feature Communication找到有关此主题的更多信息。

基于功能的UI组合 (Feature Based UI Composition)

It is common for a UI component to be an accumulation of sub-components that span several features. As a result, UI Composition is a very important part of Cross Feature Communication.

UI组件通常是跨越多个功能的子组件的累积。 因此, UI合成是跨功能通信中非常重要的部分

In support of this, feature-u introduces the withFassets() Higher-order Component (HoC) that auto-wires fasset properties into a component. This is a common pattern popularized by Redux connect() (simplifying component access to application state).

为了支持这一点, feature-u引入了withFassets()高阶组件(HoC),该组件可以自动将fasset属性连接到组件中。 这是Redux connect()普及的一种通用模式(简化了组件对应用程序状态的访问)

Here is how a component would access a company.logo (defined by another feature):

这是组件访问company.logo (由另一个功能定义)的方式

The withFassets() HoC auto-wires named feature assets as component properties through the mapFassetsToPropsStruct hook. In this example, because the Logo property is a component, MyComponent can simply reference it using JSX.

withFassets() HoC通过mapFassetsToPropsStruct挂钩自动将命名为要素资产的线作为组件属性。 在此示例中,因为Logo属性是一个组件,所以MyComponent可以简单地使用JSX引用它。

You can find more information about this topic in UI Composition.

您可以在UI Composition找到有关此主题的更多信息。

资源合同 (Resource Contracts)

It is common for UI Composition to be represented as a contract, where a component in one feature has a series of injection needs that are to be supplied by other features.

UI合成通常表示为合同,其中一个功能部件中的组件具有一系列注入需求,这些需求将由其他功能部件提供。

The fassets aspect has additional constructs to facilitate this contractual arrangement, allowing feature-u to provide more validation in the process.

fassets aspect具有其他结构以促进这种合同安排,从而允许feature-u在过程中提供更多的验证。

Rather than just defining resources in one feature and using them in another:

不仅仅是在一个功能中定义资源而在另一个功能中使用资源:

  • A given feature can specify a series of injection needs using the fassets.use directive. This identifies a set of injection keys that uniquely identify these resources.

    给定功能可以使用fassets.use指令指定一系列注射需求。 这将标识一组唯一标识这些资源的注入密钥

  • Other features will supply this content using the fassets.defineUse directive, by referencing these same injection keys.

    其他功能将使用fassets.defineUse指令(通过引用这些相同的注入键)提供此内容。

This represents more of a pull philosophy. It gives feature-u more knowledge of the process, allowing it to verify that supplied resources are correct.

这更代表了一种拉动哲学。 它使Feature-u对过程有了更多的了解,从而可以验证所提供的资源是否正确。

Wildcards (*) can be used to add additional dynamics to the process, allowing features to inject their content autonomously.

通配符( * )可用于向流程添加其他动态信息,从而允许功能自动注入其内容。

Here is a main feature that is pulling in a series of sub-components (links and bodies) from other features:

这是一个main功能,它从其他功能中引入了一系列子组件(链接和主体)

main feature:

主要特征:

Because our specification includes wildcards, a series of definitions will match!

由于我们的规范包含通配符,因此一系列定义将匹配!

Here is the MainPage component that fulfills the usage contract:

这是履行使用合同的MainPage组件:

When withFassets() encounters wildcards (*), it merely accumulates all matching definitions, and promotes them as arrays.

withFassets()遇到通配符( * )时,它仅累积所有匹配的定义,并将它们提升为数组。

Through this implementation, any feature may dynamically inject itself in the process autonomously! In addition, this dynamic implicitly handles the case where a feature is dynamically disabled (very kool indeed)!!

通过此实现, 任何功能都可以自动将自身动态地注入到流程中 ! 另外,此动态隐式处理动态禁用功能的情况(实际上是非常愚蠢的)

The following snippets are taken from other features that supply the definitions for the content to inject:

以下摘录摘自其他功能,这些功能提供了要注入的内容的定义:

cart feature

购物车功能

search feature

搜索功能

Two external features (cart and search) define the content that is requested by the main feature.

两个外部功能( 购物车搜索 )定义了主要功能所要求的内容。

The fassets.defineUse directive requires that the resource keys match a fassets.use feature request. This is the contract that provides feature-u insight when enforcing it's validation.

fassets.defineUse指令要求资源密钥与fassets.use功能请求匹配。 这是在执行验证时提供功能-u洞察力的合同。

SideBar: Because we are also dealing with navigation, we introduce react-router into the mix (with the Link and Route components). Because of RR's V4 design, our routes are also handled through component composition (see Feature Based Routes for more information).

SideBar :因为我们还处理导航,所以我们将react-router引入了混合(带有LinkRoute组件)。 由于RR的V4设计,我们的路线也通过组件组成来处理(有关更多信息,请参见Feature Based Routes )

You can find more information about this topic in UI Composition.

您可以在UI Composition找到有关此主题的更多信息。

功能启用 (Feature Enablement)

Features can be dynamically disabled by setting the Feature.enabled boolean property (part of the Built-In aspects):

可以通过设置Feature.enabled布尔属性( Built-In aspects )来动态禁用功能:

In this example, it is just as though the sandbox feature doesn't exist. In other words it has been logically removed.

在此示例中,就好像sandbox功能不存在一样。 换句话说, 它在逻辑上已被删除

Typically, this indicator is based on some run-time expression, allowing packaged code to be dynamically enabled/disabled during the application’s start-up process:

通常,此指示器基于某些运行时表达式,从而允许在应用程序的启动过程中动态启用/禁用打包的代码:

This dynamic is useful in a number of different situations. For example:

在许多不同情况下,此动态很有用。 例如:

  • some features may require a license upgrade

    某些功能可能需要升级许可证
  • other features may only be used for diagnostic purposes, and are disabled by default

    其他功能只能用于诊断目的,并且默认情况下处于禁用状态

You can find more information about this topic in Feature Enablement.

您可以在Feature Enablement找到有关此主题的更多信息。

综上所述 (In Summary)

The following diagram summarizes feature-u’s Basic Concepts (as discussed above):

下图总结了feature-u的基本概念(如上所述)

好处 (Benefits)

There are many benefits in using feature-u!

使用feature-u有很多好处!

The two fundamental artifacts from which most benefits are derived are:

可以从中获得最大收益的两个基本工件是:

  • A formal means by which features can collaborate with one another (Cross Feature Communication), making them truly plug-and-play

    一种正式的方式,功能可以相互协作( Cross Feature Communication ) ,从而使其真正地即插即用

    This includes the ability for

    这包括

    UI Composition to cross feature boundaries. It even allows UI Content to be injected autonomously. This is something that has to be seen ... it shows off feature-u very well.

    UI Composition可跨越要素边界。 它甚至允许UI内容自动注入。 这是必须要看到的东西……它很好地展示了功能-u

  • A significant reduction in boilerplate code through:

    通过以下方式大大减少了样板代码:

    Auto configuration of the frameworks in-use

    自动配置使用中的框架

    (via plugin extensions — Extendable aspects)

    (通过插件扩展- Extendable aspects )

    Startup initialization that is encapsulated within features

    封装在功能部件中的启动初始化

    (via Application Life Cycle Hooks)

    (通过Application Life Cycle Hooks )

The following list of benefits can be directly correlated to the considerations that formed the basis of why feature-u was developed (see: Why feature-u?).

以下好处列表可以直接与构成为什么开发功能-u的基础的注意事项相关联(请参阅: Why feature-u? )

  1. Feature Encapsulation: isolating feature boundaries improves code manageability

    功能封装: 隔离功能边界可提高代码可管理性

  2. Feature Collaboration: promote Cross Feature Communication through a well-defined feature-based Public Interface

    功能协作: 通过基于功能的定义明确的公共接口促进跨功能通信

  3. Feature Based UI Composition: facilitate seamless cross-feature component composition

    基于功能的UI合成: 促进无缝的跨功能组件合成

  4. Application Life Cycle Hooks: features can initialize themselves without relying on an external process

    应用程序生命周期挂钩: 功能可以在不依赖外部进程的情况下进行自身初始化

  5. Feature Enablement: enable/disable features through a run-time switch

    功能启用: 通过运行时开关启用/禁用功能

  6. Minimize Feature Order Dependency Issues during in-line code expansion

    内联代码扩展期间 最大程度地减少功能订单相关性问题

  7. Framework Integration: automatically configure used framework(s) (matching the app’s run-time-stack) by accumulating all feature aspects (employing an extendable API)

    框架集成: 通过累积所有功能方面(使用可扩展的API)自动配置使用的框架(与应用程序的运行时堆栈匹配)

  8. UI Component Promotion: features can autonomously promote their UI components through Feature Based Route Management

    UI组件升级: 功能可以通过基于功能的路线管理自主 升级 其UI组件

  9. Single Source of Truth: is facilitated in a number of ways within a feature’s implementation

    单一事实真相: 在功能实现中以多种方式得到促进

  10. Simplified App Startup: launching an app can be accomplished through a single line of executable code!

    简化的应用程序启动: 启动应用程序可以通过一行可执行代码来完成!

  11. Operates in any React Platform React Web, React Native, Expo, etc.

    在任何React平台上运行 React Web,React Native,Expo等

  12. Plug-and-Play: features can be more easily added or removed

    即插即用: 可以更轻松地添加或删除功能

feature-u allows you to focus your attention on the “business end” of your features!

feature-u使您可以将注意力集中在功能的“业务端”上!

Go forth and compute!!

继续计算!

参考文献 (References)

翻译自: https://www.freecodecamp.org/news/feature-u-v1-b84e2372c5e6/

feature功能

 类似资料: