关于您的方法的一些想法:
我想在每个应用程序清单中有一些重要的应用程序数据(如路由名称),并让主机应用程序读取它们。
为什么子应用程序必须知道它的路由器配置manifest.json
?您的主机应用程序负责编排您的所有子应用程序。它是一个,它应该知道路由到特定子应用程序的映射。
更详细一点:首先将子应用程序隔离可能是有原因的——它们是自给自足的,并且彼此独立且独立于主机。例如,想象一下,您可能想要重用其中一个应用程序并将它们作为独立应用程序运行。这也是为什么反其道而行让孩子们在宿主中注册自己的原因并不理想。因为这会在子节点和宿主节点之间强制执行更紧密的耦合——子节点必须知道,它被用于一些更大的应用程序中。
子应用
关于子应用,它可以只导出一些可运行的回调,如果路由匹配,主机将调用这些回调。ReactElement
在您使用 React 的情况下,导出将由主机呈现的内容可能就足够了。这个入口点也可以使用 Webpack 以捆绑过程的形式创建。
// as ReactElement
export const FooChildElement = <div>I am Foo child</div>
// as Component
export const FooChildComp = () => <div>I am Foo child</div>
儿童应用程序的编排
我想避免必须在主机中维护当前应用程序的列表,以便代码尽可能可重用。
除了知道所有子应用程序和路由器配置的主机层之外,您可以做的是创建一个单独的编排层。它可以提供一张地图route -> Runnable child app entry point
。主机读取该映射并将其注入其路由器,有效地从知道当前使用的应用程序列表中解脱出来。import
尽管如此,为了运行它们,它仍然对子应用程序有一些传递依赖/ 。您应该问自己,是否需要将主机与编排分开。正如您所说,您可以在构建过程(Webpack)中动态创建导入,但为什么不将这种关系硬连接到项目中的一个特定位置作为纯 JavaScript 对象呢?
export const routeToChildMapping = {
"this/is/a/foo/route": {
name: "foo",
entry: FooChildElement
},
"this/is/a/bar/route" : { ... }
}
主持人
有了这个,主机只知道导出的映射,如果路由匹配则运行应用程序,执行一些错误处理和其他信封任务。
const Router = ({route}) => routeToChildMapping[route].entry
// here getUrlSomewhere simplified
const MyHostApp = () => <Router route={getUrlSomewhere()}/>
我试图简化大局并遵守KISS
这里,因为一开始不要使事情过于复杂。当然,这高度依赖于你的构建环境和项目。因此,请随时根据您的需求/要求调整该概念!