Load React JS component from external script in “run time”

后端 未结 2 2009
走了就别回头了
走了就别回头了 2021-01-06 00:06

I\'m using React JS + webpack. General case that I need to resolve is to dynamically load React components that were not bundled with main application. Kind of pluggable com

相关标签:
2条回答
  • 2021-01-06 00:13

    It sounds like you are asking how to externalize React. If so, you can list libraries as "externals" in your webpack.config.js file:

    webpackConfig.externals = {
      "react": "React",
      "react-dom": "ReactDOM",
      ...
    }
    
    0 讨论(0)
  • 2021-01-06 00:20

    With webpack 5 you can now do this via module federation.

    The basic idea is that you "expose" exports from one project to be used in another:

    App 1 (uses Button from 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 (exposes 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"],
        })
      ]
    
    

    Here is a repo containing various examples.

    0 讨论(0)
提交回复
热议问题