React Remote Module Federation Plugins
This repo includes a simple react front end host and rust back end. Back end serves remote plugin when placed in backend/plugins
folder.
Front end host will use any remote plugins that are served by backend and in development mode any local plugins that are in frontend/src/plugins
folder (local plugins are hot reloadable)
To run backend cargo run
from backend folder.
To run front end yarn install && yarn start
from frontend folder.
To build and move First plugin to be served by backend yarn install && yarn build && yarn copy
from frontend/src/plugins/First
folder, similar with Second plugin.
You don't need to build plugin for front end to use it in develop mode, and you will only need to yarn install
in plugin folder if plugin adds a new dependency (in fact i've noticed that if all plugins are built it takes some time for front end to start up, I haven't been able to figure it out, but if at least one node_modules folder is deleted it's back to being fast)
Each plugin need to export 'default' from plugin.tsx matching Plugins
type, plugins in this version are made to bundle together implementations of various plugin interfaces, allowing one plugin to extend many areas of the app
Hot reload is enabled by loading plugins from frontend/src/plugins
folder in development mode using lazy import:
plugins-example/frontend/src/plugin.tsx
Lines 62 to 69 in 091f79a
And LOGAL_PLUGINS are loaded in in webpack config:
This is different to remotely served built plugins using module federation. Those are loaded by first getting a list of plugins form the server then fetching them individually and binding to the application:
plugins-example/frontend/src/plugin.tsx
Lines 53 to 57 in 091f79a
See module federation dynamic remote example for further explanation of how loadPlugin method works.
Plugins are stored in zustand
store, which is populated on startup, when they need to be displayed they are loaded via React.lazy:
plugins-example/frontend/src/plugin.tsx
Lines 88 to 93 in 091f79a
This repo is meant to shown an example of a pattern for plugins for your a web application. It's hard to know which areas will need to be extendable/pluggable in the future, if a simple pattern is available, it should be straight forward to extend application with a plugin where it's applicable.
This diff shows the changes to introduce new plugin after copying existing plugin, note you do have to restart webpack to see new plugin, but after it's registered hot reload should work.
Column plugin exports a StateLoader component which can be used to fetch data for all of the rows (based on the ids and values in normal invoice rows), a zustand state is shared with each column to then get the relevant data for the column field