copenndthagen
copenndthagen

Reputation: 50760

Microfrontend Fixing Conflicting styles issue

I am having a Microfrontend application, which internally uses Material UI dependency (at the Host and Child MFE).

I am running into a CSS conflict issue where in the problem occurs if the order of loading styles are as below;

<!-- Default Material UI styles -->
<style data-jss data-meta="MuiButtonBase">/* ... */</style> 
<!-- Your Button Material UI styles -->
<style data-jss data-meta="MuiButtonBase">/* ... */</style>
<!-- THE PROBLEMATIC STYLES: Default Material UI styles, AGAIN -->
<style data-jss data-meta="MuiButtonBase">/* ... */</style>

I am trying to understand the solution provided at this page https://github.com/module-federation/module-federation-examples/issues/1071 The solution I am referring on this page is where it is using the StylesProvider (where it says "The solution to me was to isolate the classNames per micro-frontend, so no micro-frontend can inject jss styles that can override the others.").

However I am quite confused as to how/where to this StylesProvider to? Specifically my question is if this StylesProvider is to be applied only at the Host or even at the Child MFE.

My setup is something as below;

In my Host App.js, I have

import { Route, Routes, BrowserRouter } from 'react-router-dom';
import {HashRouter as Router} from 'react-router-dom';
import React, { useEffect, useState } from 'react';

function App() {
  return (
    <ThemeProvider theme={theme}>
        <div>HOST APP: <br /></div>
        <a href="/my-inq">Link to child app</a>
        <Route exact path="/myinq-ui">
          <MyInqWrapper  />
        </Route>
    </ThemeProvider>
  );
}

export default App;

In MyInqWrapper.jsx, I have

import React from 'react';
import { Spinner } from 'reactstrap';

// @ts-ignore
// eslint-disable-next-line import/no-unresolved
const MyInq = React.lazy(() => import('myInqMfe/MyInq'))

const MyInqWrapper = ()=>{
  return(
    <div>
      <React.Suspense  fallback={<Spinner/>}>
        <MyInq />
      </React.Suspense>
    </div>
  )
};

export default MyInqWrapper;

Also, my Child App.js is as below;

import { Route, Routes } from "react-router-dom";
import MyInq from "./my-inq/MyInq";

function App() {
  return (
    <>
      <div>
        <Router>
                <Route exact path="/search">
                  <Search url={user} />
                </Route>
                <Route exact path="/myinq-ui">
                  <MyInq />
                </Route>
              </Router>
      </div>
    </>
  );
}

export default App;

Upvotes: 0

Views: 974

Answers (1)

felixmosh
felixmosh

Reputation: 35573

One idea is to add a prefix selector to your child MFE (my-unique-child-prefix).

By using MUI experimental API ClassName generator that allows you to define the shape of the css selectors (since v5.0.5),

// Child app class name setup
// create a new file called `MuiClassNameSetup.js` at the root or src folder.
import { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material/className';

ClassNameGenerator.configure(
  // Do something with the componentName
  (componentName) => `my-unique-child-prefix-${componentName}`,
);

Upvotes: 0

Related Questions