TLDR; How to use a single context between react micro frontends?
The application is divided into multiple Microfrontends or react apps. Each of these is running on a different port. A container is hosting other Micrfrontends. Each one is a separate react app and it is a runtime integration. (I have used martinfowler example to implement micro frontend)
Currently passing some data via URL and browser storage (localStorage/cookies) to other Microfrontends.
I need to pass the data across these react apps (MFEs) using React Context.
I have defined ReactContext Provider in Container (ReactApp1) and stored value (say color=black). To access this color inside the lower level Microfrontend (ReactApp2) we need the context to be available from any micro frontend. How to make it available?
(NOTE: I don't want to use localStorage or cookies for global data sharing)
<Container>
<LowerLevelMFE1/>
<LowerLevelMFE2/>
...
</Container>
Webpack 5's Module Federation & ModuleFederationPlugin is the best way I've found to achieve this architectural pattern.
In essence you create a "host" application that wraps the React.context around a "remote" component. This "remote" is actually another component in a standalone application that is being exposed as a remote through its webpack config file. In this 2nd application you would consume the context as normal using React.useContext.
You can find a full example of this setup here on github.
A few things to note:
Both applications will need to consume this Context's source code so moving it into its own package is preferred.
Your Context consuming application will still need, what I call in MFEs, "developer scaffolding". In this case that would be a simple component that wraps your <ContextConsumer /> in a <ContextProvider /> that you are importing from your shared Context package I mentioned in 1.
Remember this app with scaffolding is only exposing the <ContextConsumer /> which you need to make sure to specify in the webpack config.
I think sharing context between Micro-frontends is an anti-pattern and should be avoided if you can. If you use context to share data, you will automatically couple the MFes that depend on the context, eliminating the benefits of independent deployments by introducing coordination and a dependency.
My advice is that each micro-frontend loads the data they need and if there is communication need it, you need an api or a contract to handle this communication.
I think if you need that type of comunication between the mfe's then they are splited wrong.
As Ruben says, is an anti pattern.
Related
So the question is if it is possible to split a React app into two different separate apps hosted on two different hosts, where the app A is a kind of a frame which controls the app B and C in the future. I have a problem, where I would like to make a common fundament for both apps (the A app) and then load two other as a content of it. It would be as if I had lazy loading with a bundle fetched from a different place. I was thinking about three main possibilities:
Iframe
Single SPA project from github
using ReactDOM.render method
I am not sure if it is possible at all, beacuse there still may be a problem with React Router - does the inside app have access to manipulate the browser routing?
It is quite possible to split your react Application into multiple smaller react applications.
Suppose you have a react application such as an e-commerce platform . You can choose to write the cart Page using a separate react-App and the products page using another separate react app and integrate them together using Module Federation Plugin webpack/lib/container/ModuleFederationPlugin.
A good reason to do something like that would be to develop different parts of your application in isolation ..and they can be taken care by different teams altogether.
There is a udemy course that teaches you exactly that. Very much recommended. You can make react dependency as singleton to avoid several installs of react.
All 3 of these options you've stated are valid and can be used to share components but there are few disadvantages to each one, for example- iFrames makes it hard to create responsiveness, ReactDOM splits your app so that the different parts won't have the same global scope...
Module-Federation is the best and most efficient way to share remote components that i know of, here is a github link to a basic project.
The MF plugin makes use of webpack's abilities, which means that the shared components are being consumed as runtime objects of the app's scope, rather then as a promise of an iframe.
NOTE: Debugging and updating a Module Federation project is a much deeper task then debugging a create-react-app application, you'll need to share dependencies correctly and remember to update desired changes at all the right places all the time.
This is not possible. Each react app can only have a single package.json in the hierarchy. if you nest it, the app will fail and say you have several installs of react. what you should do is think more react minded and objecty. You can have a folder for common components to share inside src/. You can also have src/A which is one "app". src/B which is another.
What you described in your question is exactly what you should do, just dont think of it as a react app separation, rather a seperation of component and app inside the src folder. App A can be comprised of components from /components as well as App B.
I'm building an applications front-end using ReactJS and redux state container. This app (core) is going to be reused in some various projects in some of which I will need some additional features / extensions (plugin). These need to be separated from the core. The app and extensions are rendered on client's browser (I'm not pre-rendering anything on the server).
I'm looking for a way to:
a) create an "thrird party" plugin which can access the core apps state
b) render an "thrird party" plugin component from within the core app
Any ideas?
Thanks ;)
#romek from what I understand is that your use case sounds like a classic case of scaling ( modularity ) your software. What I'd suggest is that having a clear understanding of the parts involved in making a component / container work. These are ( as per my experience ) -
Reading data from the store ( selectors ).
Writing data to the store ( reducers ).
Handing other side-effects / interactions ( thunk or sagas).
The actual component which consumes these modules.
Now once you've identified all these pieces ( or more ), you make every 3rd party component confer / implement this design. Now you just need to import the component and render it.
Hope this helps! 😇
My team is creating the administration panel of a CMS using React, Typescript, TSX and Webpack. Each page of the administration panel has been created as a React component, and each page contains many other child components (one for each section).
The CMS distribution currently includes a bundled version of the javascript needed to run the web app, but not the original TSX files.
Now, we would like to make it possible to the developers using our CMS to extend the web app by
1) Injecting additional sections into the UI using a "slot-fill" approach
2) Possibly even overriding the existing sections rendering a different component in the same place.
<div>
<SidebarComponent />
<Section1Component />
<Section2Component />
// How to inject a possible PluginComponent here?
</div>
From the research we've conducted so far, there seem to be no "official" way to do this, so I'm wondering what would be the best approach in this case.
I am facing the same issue where I need a component from a plugin to interact with a component from another plugin with a hook system. I have a created a small codesanbox with the same approach adapted to your need.
Basically the approach is to create a injectedComponents.js at the root of your plugin that specifies in which plugin and area your component needs to be injected.
Here is ademo
single-spa has some good options in order to achieve this.
Please see if it can be help for you.
Microfrontends
Parcels
I am late to this but
Just create a utility class with registry function, and register each component to the registry (just dictionary of key value pair, where key is a constant and Value is the component). T
Then when you display a component in your base app, get it from the registry using a key. Then once you publish this whole base app as package ( make sure to export the utility registry). A user can register a component with the same name and override the default component.
For communication between totally independant components, you can use and EventEmitter
Learning a little React currently. I'm finding myself confused about some of the utility here. One sticking point that seems to (for me, at least) undermine it's value is that If I want to sync my UI to data residing on the server (which can and will change), I need to manually poll the server? Aside from component-based architecture, I'm not sure how this is getting me further than well structured and logically implemented AJAX. Even in the React docs, they're using JQuery in this regard. https://facebook.github.io/react/docs/tutorial.html#updating-state
I'm sure I'm missing the forest for the trees or whatever.
Thanks!
React is (citing their page)
a javascript library for building user interfaces
The main focus is to build a view layer for your application. This means you have full freedom in choosing what to use to fetch your data. For simple uses it can be jQuery or fetch.
It's generally recommended to not fetch data directly in your components and use one of Flux pattern implementations, e.g. Redux.
If your application has to be constantly powered by new data from server you can think about using something like RethinkDB on your backend and connect it to Flux store on your frontend.
All:
I am pretty new to React from AngularJS. In AngularJS, there is service dependency inject which can provide a service instance to do data fetching, processing, etc., other than UI operation. I wonder how to do this(or implement that injection) in React component?
Thanks
I prefer to create a service in another file that exposes the 'public' functions through module.exports.
e.g.
module.exports = {
foo: function(){ return bar; }
}
which is then referenced by Components using
import myService from './routetoservice/myService'
An Extension to Michael Dunn's Answer
This is the actual answer ,
Service pattern is not limited to any programming language or
library.
We can implement this concept in any language , Even we can
implement this in react
A tiny service can be created on server OR in ui browser in Javascript that serves some logical purpose
It gives us benefits of code availability, code management , code isolation of particular logic
Its a very native way for code availability, code management , code isolation of particular logic
If we compare redux/flux vs services ,redux/flux also serve these purpose's
Currently i am using redux and its actions , and also created my tiny services on ui when required.
No need to use OTHER NPM MODULES FOR CREATING SERVICES , Just Michael Dunn's solution is enough
In reactjs we use the flux pattern to provide data handling. Here is an example of that with reflux. React with Flux: is this the dogmatic pattern or are there equal/better options?.
React seems philosophically opposed to services in the Angular sense, apparently preferring tight coupling of UI and logic.
But I have found a react-services module, which seems to offer what you are after:
• separate your component and application state by introducing a service layer that takes care of propagating changes through your application
• manage component dependencies in an explicit, testable way
• there's no events and no lifecycle management - everything is done automatically for you
• it's tiny and easy to understand - the core is less than 100 lines of code
https://medium.com/#alshdavid/react-state-and-services-edb95be48851
Here's an article showing how to do it with nothing but React Context and rxjs