【问题标题】:Load React JS component from external script in "run time"在“运行时”从外部脚本加载 React JS 组件
【发布时间】:2017-03-29 15:25:02
【问题描述】:

我正在使用 React JS + webpack。 我需要解决的一般情况是动态加载未与主应用程序捆绑的 React 组件。一种可插拔的组件,可以独立于主应用程序开发,然后由应用程序动态加载,而无需重新构建整个应用程序。

具体情况如下。

我有两个完全独立的模块(即使用不同的 package.json 和 webpack.config.js 构建):

  • MainApp
  • 一些Component

我需要实现以下行为:

  1. 已加载并初始化带有MainApp 的页面。
  2. MainApp 动态查找包含 Component 的 .js 文件的 url(例如,通过向网络服务器发出 GET 请求)。
  3. MainApp 加载带有Component 的.js 文件并将其作为<script> 包含在页面中
  4. MainApp 在渲染时使用已加载的 Component

在 react js + webpack 中是否可以使用这种用例?

【问题讨论】:

  • GET请求返回一个编译好的组件?
  • 它返回有效的 .js 文件,而不是 .jsx(如果你在谈论它)。
  • 您找到解决方案了吗?
  • 不。我为我的特定任务找到了另一种解决方案,但它不能解决一般问题。我从 json 描述(如github.com/mozilla-services/react-jsonschema-form)动态创建组件。它使动态组件的外观和行为非常有限,但对我来说没问题

标签: javascript node.js reactjs webpack


【解决方案1】:

听起来你在问如何外部化 React。如果是这样,您可以在 webpack.config.js 文件中将库列为“外部”:

webpackConfig.externals = {
  "react": "React",
  "react-dom": "ReactDOM",
  ...
}

【讨论】:

  • 我需要加载在“编译时”(嗯,捆绑时)不存在的组件。我认为您在谈论延迟加载,因此在捆绑应用程序时所有组件都是已知的。不一样
【解决方案2】:

使用 webpack 5,您现在可以通过 module federation 执行此操作。

基本思想是您“公开”一个项目的导出以在另一个项目中使用:

应用 1(使用来自 app2 的按钮)

<!-- public/index.html -->
<html>

<head>
  <!-- remote reference to app 2 -->
  <script src="http://localhost:3002/remoteEntry.js"></script>
</head>

<body>
  <div id="root"></div>
</body>

</html>

//app.ts
import * as React from "react";

const RemoteButton = React.lazy(() => import("app2/Button"));

const App = () => (
  <div>
    <h1>Typescript</h1>
    <h2>App 1</h2>
    <React.Suspense fallback="Loading Button">
      <RemoteButton />
    </React.Suspense>
  </div>
);

export default App;

//... webpack.config.js
plugins: [
    new ModuleFederationPlugin({
      name: "app1",
      library: { type: "var", name: "app1" },
      remotes: {
        app2: "app2",
      },
      shared: ["react", "react-dom"],
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ]

应用 2(显示按钮)

// src/Button.ts
import * as React from "react";

const Button = () => <button>App 2 Button</button>;

export default Button;

//... webpack.config.js
 plugins: [
    new ModuleFederationPlugin({
      name: "app2",
      library: { type: "var", name: "app2" },
      filename: "remoteEntry.js",
      exposes: {
        Button: "./src/Button",
      },
      shared: ["react", "react-dom"],
    })
  ]

这是repo containing various examples

【讨论】:

  • 我也有同样的需求。我需要使用一个外部 .js 文件,该文件本身包含一个要在主反应应用程序中使用的反应组件。需要时在运行时动态加载外部 .js 文件。我将 webpack 配置为让外部响应和 react-dom。但是每次加载外部 .js 时,我都会收到以下错误:“[ReferenceError: react is not defined]”。如何允许外部 .js 文件引用主应用程序中的反应库?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 1970-01-01
  • 2019-10-14
  • 2021-06-27
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多