在“运行时”从外部脚本加载React JS组件

Load React JS component from external script in "run time"

本文关键字:运行时 React JS 加载 组件 从外部 脚本      更新时间:2023-09-26

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

特殊情况如下。

我有两个完全分离的模块(即使用不同的包构建)。Json和webpack.config.js):

  • MainApp
  • 部分Component

我需要实现以下行为:

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

这样的用例在react js + webpack中可能吗?

在webpack 5中,你现在可以通过模块联合来做到这一点。

基本的思想是你"公开"一个项目的导出,以便在另一个项目中使用:

App 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",
    }),
  ]

App 2 (expose Button)

// 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"],
    })
  ]

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

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