草庐IT

javascript - 动态加载 React 组件

coder 2024-07-24 原文

我正在考虑构建一个网络应用程序,人们可以在其中安装插件。我希望插件能够定义将呈现到页面的 React 组件,而无需在安装插件后重新编译主 JavaScript 包。

所以这是我正在考虑的方法:

  • 将主要的 JavaScript 与 React 捆绑为 external library , 使用 webpack。
  • 让插件作者也使用 React 作为外部库编译他们的组件。

这样一来,我只运行了一个 React 实例。我或许可以对其他一些常用的库执行相同的操作。

接下来的问题是如何从服务器动态加载这些插件组件。假设我有以下组件:

class PluginRenderer extends React.Component{
  componentWillMount() {
    getPluginComponent(`/plugins/${this.props.plugin}/component.js`).then((com) => {
      this.setState({pluginComponent: com});
    })
  }

  render() {
    var Plugin = this.state.pluginComponent;
    return Plugin ? <Plugin {...this.props} /> : "Loading..."
  }
}

如何实现getPluginComponent

最佳答案

这是一个有趣的问题,几个月前我在客户工作中也遇到过,而且我没有看到太多的文档方法。我们所做的是:

  1. 各个插件将是单独的 Webpack 项目,我们为其提供模板或生成项目模板的 CLI 工具。

  2. 在这个项目中我们定义Webpack externals对于已在核心应用程序中使用的共享 vendor 库:React、Redux 等。这告诉插件不要将它们包含在包中,而是从 window 中的变量中获取它们我们在核心应用程序中设置。我知道,这听起来很糟糕,但这比让所有插件重新包含 1000 个共享模块要好得多。

  3. 重用 external 的概念,核心应用程序还通过窗口对象向插件提供一些服务。最重要的一个是 PluginService.register()您的插件在初始化时必须调用的方法。我们在这里反转控制:插件负责向核心应用程序说“嗨,我在这里,这是我的主要导出(如果它是 UI 插件,则为组件)”。

  4. 核心应用程序有一个 PluginCache 类/模块,它只保存加载插件的缓存(pluginId -> 插件导出的任何内容、fn、类等)。如果某些代码需要插件来呈现,它会向此缓存请求。这具有允许返回 <Loading /> 的好处或 <Error />插件未正确加载时的组件,等等。

  5. 对于插件加载,此 PluginService/Manager 加载插件配置(我应该加载哪些插件?)然后创建动态注入(inject) script标签加载每个插件包。捆绑完成后,register第 3 步中描述的调用将被调用,并且您在第 4 步中的缓存将具有该组件。

  6. 与其尝试直接从您的组件加载插件,不如从缓存中请求它。

这是一个非常高层次的概述,几乎与我们当时的需求相关(这是一个类似于仪表板的应用程序,用户可以在其中动态添加/删除面板,所有这些小部件都作为插件实现)。

根据您的情况,您甚至可以用 <Provider store={ theCoreStore } 包装插件> 所以他们必须访问 Redux,或者设置某种事件总线,以便插件可以相互交互……前面有很多东西需要解决。 :)

祝你好运,希望对你有所帮助!

关于javascript - 动态加载 React 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44778265/

有关javascript - 动态加载 React 组件的更多相关文章

  1. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  4. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  5. ruby - 在 Ruby 中动态创建数组 - 2

    有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.

  6. ruby - 是否可以将 IRB 提示配置为动态更改? - 2

    我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. ruby-on-rails - carrierwave:在序列化动态属性上安装 uploader - 2

    首先,我使用的是rails3.1.3和来自master的carrierwavegithub仓库的分支。我使用after_init钩子(Hook)来确定基于属性的字段页面模型实例并为这些字段定义属性访问器将值存储在序列化哈希中(希望它清楚我是什么谈论)。这是我正在做的事情的精简版:classPage省略mount_uploader命令让我可以访问我想要的属性。但是当我安装uploader时出现错误消息说“nil类的未定义新方法”我在源代码中读到有方法read_uploader和扩展模块中的write_uploader。我如何必须覆盖这些来制作mount_uploader命令使用我的“虚拟

  9. ruby - 在 Ruby 中动态生成多维数组 - 2

    我正在尝试动态构建一个多维数组。我想要的基本上是这样的(为简单起见写出来):b=0test=[[]]test[b]这给了我错误:NoMethodError:undefinedmethod`test=[[],[],[]]而且它工作正常,但在我的实际使用中,我不会事先知道需要多少个数组。有一个更好的方法吗?谢谢 最佳答案 不需要像您正在使用的索引变量。只需将每个数组附加到您的test数组:irb>test=[]=>[]irb>test[["a","b","c"]]irb>test[["a","b","c"],["d","e","f"]]

  10. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

随机推荐