Webpack 5 Dashboard

Webpack 5 Dashboard

To prove if using Federated Modules for a dashboard would be a good thing I think you'd have to prove three technical capabilities:

  • Load dashboard widget code dynamically at runtime (no requirement to rebuild to add new widgets)
  • The host page shouldn't need to be based on the code loading technology
  • Share code with the widgets
  • Share style theming with the widgets

To test this out I built this simple dashboard starting with a Create-React-App (which is Webpack 4 currently).

The big pie chart panels are actually dashboard widgets. And the underlying page is the dashboard host.

The video of this article walks through the full solution that covers all the four requirements.

Using Webpack 5 Federated Modules for a Dashboard

And the code for the article is on github.

Getting the dashboard widgets set up with Webpack 5 is fairly straightforward. The real trick is getting that code loaded, and the initialized properly, into our Create React App.

To load the code I use a simple hook that adds script tag onto the page and listens for onload and then return a ready flag when it fires.

We then use that hook in a React component called RemoteReactComponent which loads the code, then overrides sets the overrides before use its factory function to create a new component instance.

It's this code right here:

  if (ready) {
    const o = global.__webpack_require__ ? global.__webpack_require__.o : {};
    window[scope].override(
      Object.assign(
        {
          react: () => Promise.resolve().then(() => () => require("react")),
          "react-dom": () =>
            Promise.resolve().then(() => () => require("react-dom")),
        },
        o
      )
    );
  }

The problem is that you have two React instances on the page. The first is from the host app itself, and that's the React that we want. The second is the React instance that the Dashboard Widget Federated Module may load if it doesn't see a React instance is already available.

So that's what this code is telling the Webpack code on the page, we have a react and react-dom instance already, please use those instead of loading your own.

This is critical for any shared libraries that you have between the dashboard host and the dashboard widgets. So in the example we also share recoil, @emotion/core and emotion-theming.

Beyond that all you have to do is make sure you invoke the factory method properly, and you should be good to import Federate Modules in to any environment, even if the host application is not Webpack 5.

Once you have the setup working you can share context and state with them just like a React component that is bundled directly into the application at build time.

It's worth noting that you don't have to do any of this work if the host application is on Webpack 5 and your specify your remotes at build time. In that case you can use import and that will handle managing all the overrides for you.

Happy Webpack 5 Federated Moduling!