Microfrontends React/Component based splitting - reactjs

Background:
I am confronted with the task to modernize a tool and convert it to microservices with a react frontend. My idea was to have a general top-level component containing e.g. the Nav and a component for each microservice that contains the functionality.
Approaches:
bundle the components locally so that it becomes effectively a monolithic frontend and the the forntend code is seperated just in the repo.
I think that would give up on the advantage of not having to redeploy your entire app for every change
lazy-load a minified bundle of each of the components from the microservice by defining them in a config file
With this approach I could just webpack each component on their own and async import it from the Main Page but maybe there would be a huge overhead
I read about component based splitting with react-loadable and bundling react-router or webpack, but I can't find information on how to load small bundles form different URL-Endpoints.
Question:
Is it possible to bundle react components on their own and import them from different Resource-URL's and how would one approach that ?(Or is React even suitable for that)

So after quite some search and experiments I found the Project Mosaic of Zalando, which is what I wanted. It offers a great way of React Component Splitting to support Micro Frontends. Note however that it is probably not suitable for smaller projects as it takes some time to get into the material and setting up all necessary applications.

Take a look at the below link:
https://www.martinfowler.com/articles/micro-frontends.html
I've recently made a project based on that article and I think that it might be what You are looking for.
I made the wrapper app which is rendering the microfrontends dynamically on the runtime based on the URL and routings. In the article above, there is a demo app showing the idea.
Every microfrontend is the separate project with it's own code repo.
https://demo.microfrontends.com/
Each app is hosted and js chunks are getting loaded on the runtime. This code might make it a little bit more clear what's going on there.
componentDidMount() {
const { name, host } = this.props;
const scriptId =micro-frontend-script-${name}`;
if (document.getElementById(scriptId)) {
this.renderMicroFrontend();
return;
}
fetch(`${host}/asset-manifest.json`)
.then(res => res.json())
.then(manifest => {
const script = document.createElement('script');
script.id = scriptId;
script.src = `${host}${manifest['main.js']}`;
script.onload = this.renderMicroFrontend;
document.head.appendChild(script);
});
}`
I hope You'll find that helpful :)
Good luck!

Related

React.js: Best practices for API's grouping

I have been using Angular for 3 years. I have created some small and big projects. In every project, I have used proper folder structure for API calls(which many resources suggest). Below is a simple example
constants.ts
export const uploadData = `${url}/uploadData`;
service.ts
uploadData(formData: FormData): Observable<any> {
return this.http.post<any>(constants.uploadData, formData);
}
And in the component file, I import the service and call the API like this
this.service.uploadData(formData).pipe(take(1)).subscribe((res) => {
// do something
});
I specify all my related APIs and services in respective folders and call them wherever I need them. It's been 5 months since I started learning React and ReactNative. Now I am comfortable with both I started doing a major project. Now, the resources I followed to learn React didn't follow the proper structure(Create the API in whichever folder is required and call it with fetch/axios). Found some resources that follow structure but not effectively like how I did it in Angular. I can't find any resources with the requirement. It would be helpful if I can get one example of how we can have the folder structure like in Angular so that I will follow the good approach, instead of ending up writing bad code. (I am using Axios)

How to test route changes with NextJS, Vitest, and React Testing Library

What is the best way to test routing in a NextJS app? I am using it as a static site generator and am not really using any server-side rendered capability. How do I test routing for the entire application? Ex, let's say my site starts on the route /first-route and I fire an event that changes the route to /second-route. How should I test that? I am trying to use Vitest and React Testing Library. I would really appreciate any guidance!
It's tricky. You may want to consider using something like Cypress for these tests as they are more like end-to-end tests.
You may get away with a tool like next-page-tester - though in my experience that causes more problems than it solves for complex apps.
But if you just want to test that something happens when the path changes, I've had good results with next-router-mock. There's plenty of options available in their docs, but a simple example might look like this:
import mockRouter from "next-router-mock";
describe('tests', () => {
it('changes the url', () => {
mockRouter.setCurrentUrl("/pizza");
})
})

How to create a Google web app using Google Apps Script, React, and MobX

I found react-google-apps-script project on GitHub, and it seems to be able to make my dreams of a React-based Google Apps Script project a reality. For a while, since I learned React (and MobX), I've been wanting to use it inside Google Apps Script projects!
Per the documentation, however, it seems to only work on dialog windows... :'(
That being said, I have a freelancing client who is looking for a UI that can interact with her Google Sheets, to which the most reasonable approach would be to create a web app. I've created Google Apps Script based web apps in the past, in fact it was my very first exposure to it. It seems like they only support raw HTML templates and jQuery .
However, knowing all that I know now, I'd like to create a simple React + MobX MVVM-based web app on the Google Apps Script. How can we use this project to get that done?
UPDATE: I should have read more carefully! This is embarassing!!
From looking at src/server/ui.js, I see that is how the main use case, injecting React project into the modals in Google Apps Script projects that control Google Spreadsheets, even gets to happen.
Here is the code from that file:
export const onOpen = () => {
const menu = SpreadsheetApp.getUi()
.createMenu('My Sample React Project') // edit me!
.addItem('Sheet Editor', 'openDialog')
.addItem('Sheet Editor (Bootstrap)', 'openDialogBootstrap')
.addItem('About me', 'openAboutSidebar');
menu.addToUi();
};
export const openDialog = () => {
const html = HtmlService.createHtmlOutputFromFile('dialog-demo')
.setWidth(600)
.setHeight(600);
SpreadsheetApp.getUi().showModalDialog(html, 'Sheet Editor');
};
export const openDialogBootstrap = () => {
const html = HtmlService.createHtmlOutputFromFile('dialog-demo-bootstrap')
.setWidth(600)
.setHeight(600);
SpreadsheetApp.getUi().showModalDialog(html, 'Sheet Editor (Bootstrap)');
};
export const openAboutSidebar = () => {
const html = HtmlService.createHtmlOutputFromFile('sidebar-about-page');
SpreadsheetApp.getUi().showSidebar(html);
};
It is worth noting that this will transpile to the back-end Google Apps Script code.
This means that we could customize this and make this more general, by editing out the onOpen method. I see it is developer's responsibility to do that :P
Great project! It's easy to follow, and I can see how I can make this my own, with MobX and MVVM!

How to render a React app in a React app (nested React apps)

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.

Splitting React App to 2 Independent Parts

The app I'm developing (Node.js + Express + React + Alt) is addressed to 2 types of crowds - Teachers, for which it is a large app with multiple routes, and students, for which it is a very small app with a single route.
I want to separate these 2 parts completely, so the code of teachers part won't be loaded when students route is rendered.
I have two reasons in mind:
Better loading times for students' app - There's no point in downloading and running that big chunk of JavaScript when I know it won't be needed.
Security Aspect - Although there's no data exposure, I'd still rather hide the code the teachers use from the students.
Is there an easy way to do this?
Can I use one React app (And one React-Router)?
Thanks for any help!
The best way to implement this is using the Webpack feature Code Spliting. This allow you automatically split your code in chunks and only load the require code when is needed.
You can see the React Router example: huge-apps
The magic happen in the internal components (require('./routes/*')), here they use the callback method to get the components and look something like this:
export default {
path: 'nameOfComponent',
getComponent(location, cb) {
require.ensure([], (require) => {
cb(null, require('./components/nameOfComponent'))
})
}
}
Require.ensure is detected by Webpack and generate a new chunk with all the code and his internal dependencies.
When the application is executed in the browser the first load only get the main chunk with the routes definition, and each router components is loaded on demand (when you change of route).
For me, this is the most clean way to do it. Because you delegate the responsibility to the build system. In Webpack 2, you could use System.import instead of require.ensure, and is a more ES6 standard.

Resources