search

Home  >  Q&A  >  body text

Isolating CSS in micro frontends when using the same library twice

I have several micro frontend react applications. All applications are technology agnostic. This means that any application can have any library as a dependency. They are using the webpack module union plugin. If other micro frontend applications have the same version, the dependency will be shared.

Micro front-end applications are divided into several groups: main micro front-end applications and sub-micro front-end applications. The main application is a container for other sub-applications. Only one subapplication can be running at a time.

Our company has UI-Kit with react components. The library includes CSS variables, global selectors (* {/* CSS rules */}).

Sub-applications can have our UI-Kit as a dependency. If the versions of UI-Kit are different, one of the sub-applications may apply the wrong styles. Workflow (how it works): I open the main app in the browser and webpack loads all the resources (JS, CSS, fonts) for the first page of the main app. After that, I open the page using Sub app 1, webpack loads the resources of Sub app 1 and inserts them into the document (the CSS styles will be inserted into the head of the document). Our UI-kit has CSS modules, but this is not enough because the names of classes are not created based on the content of CSS rules. Additionally, CSS variables may change in one of the versions. Additionally, the sub-application may not use our UI-Kit, but all * CSS rules in UI-Kit will apply to the sub-application. Additionally, two sub-applications can use different versions of the same library, and the library can use global or module CSS.

I need to apply full CSS isolation for each micro frontend application.

Last time I tried to apply a shadow DOM that supports full CSS isolation. But one of the libraries (cytoscapejs or its plugin) calls document.getElementById method. It returns null because the element it is looking for is already in the shadow root. I'm investigating the case.

Before this, I considered adding a version at the end of UI-Kit's CSS module class. But it does not make the names of CSS variables unique. Also, I don't think I can rename an external library's CSS classes from within my micro frontend app build.

Additionally, I know that style loaders can allow style tags to be added and removed using the "use" and "unuse" methods. I can use this to prevent overwriting the styles of two sub-applications. But mini-css-extract-plugin does not have this function.

I could try using :has and :not selectors, but I don't want to deal with a lot of different CSS situations (* selectors, css variables, etc.). I think this is a wrong approach.

P粉321676640P粉321676640350 days ago513

reply all(1)I'll reply

  • P粉904405941

    P粉9044059412024-01-02 00:35:28

    Check out PostCss Prefix Wrap plugin , which adds selectors to CSS prefix styles to help prevent CSS from leaking from one micro frontend to another.

    In order to use the plugin, install it and extend your webpack.config as follows:

    const PrefixWrap = require('postcss-prefixwrap')
    ...
    ...
    {
      loader: 'postcss-loader',
      options: {
        sourceMap: true,
        postcssOptions: {
          plugins: [
            PrefixWrap('#mfe_id_<appname>', {
              nested: '&',
            })],
        },
      },
    }

    Please adhere to #mfe_id_ naming and add the same ID to the topmost element in the MFE.

    advantage

    • Easy to implement and also works with nested CSS rules.
    • No need to worry about the prefix of the root (i.e. html, body) element Responsible for this by the prefixRootTags parameter. By default, this option is Set to false, indicating that the root element will not be prefixed. But will be replaced with the provided #mfe_id_.

    shortcoming

    • Requires PostCSS.

    reply
    0
  • Cancelreply