单一 spa 与材料 UI 样式的集成问题

问题描述 投票:0回答:3

我们正在尝试将 Single spa 与 React 和 Material UI 集成。 我们有 2 个带有 Material UI 的 React 应用程序:

  1. 根容器。
  2. 微前端(水疗应用程序)。

当我们集成这两个组件时,我们会出现以下错误:

看起来此应用程序中初始化了多个

@material-ui/styles
实例。这可能会导致主题传播问题、类名损坏、特异性问题,并在没有充分理由的情况下使您的应用程序变得更大。请参阅 https://material-ui.com/r/styles-instance-warning 了解更多信息。

配置文件是这样的:

webpack.config。 通过此配置,我们希望外部化,以便它使用根容器应用程序中存在的材质 ui 依赖项。

index.js。我们正在注册微前端。

index.html 我们正在使用systemjs来加载材质模块和微前端。

我们按照本页建议的步骤操作,但没有得到任何满意的结果:

https://material-ui.com/getting-started/faq/#i-have-several-instances-of-styles-on-the-page

reactjs material-ui styles single-page-application single-spa
3个回答
3
投票

我也一直在单一 Spa 微前端中的材质 UI 上苦苦挣扎,因为我对材质 UI 也有多个依赖项,这导致了随机渲染错误。

为了防止这种情况,您需要使用material-ui作为浏览器内模块,这样您的微前端就只有一份副本可以使用。为此,它需要与 SystemJS 兼容。更多信息:https://single-spa.js.org/docs/recommended-setup/#systemjs

为此,最简单的方法是使用 UMD 脚本。例如,如果您使用@material-ui/core版本4.11.3,您将需要这个脚本:

“https://cdn.jsdelivr.net/npm/@material-ui/[email protected]/umd/material-ui.production.min.js”

您必须使用其余的导入映射来加载该脚本:

例如:

    <script type="systemjs-importmap">
      {
        "imports": {
          "react": "https://cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js",
          "react-dom": "https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.production.min.js",
          "single-spa": "https://cdn.jsdelivr.net/npm/[email protected]/lib/system/single-spa.min.js",
          "rxjs": "https://cdn.jsdelivr.net/npm/@esm-bundle/[email protected]/system/es2015/rxjs.min.js",
          "@material-ui/core": "https://cdn.jsdelivr.net/npm/@material-ui/[email protected]/umd/material-ui.production.min.js"
        }
      }
    </script>

另一种可能性是使用 JSPM 将依赖项加载为导入映射。您可以在此处找到示例:https://github.com/jspm/project/issues/99

最后,您始终可以将依赖项打包到共享组件之一中并从那里共享它。由于您的共享组件是浏览器内模块,因此您将只有一份副本。

希望有用


3
投票

我的设置与上述评论相同,但它并没有完全解决我的多个微前端的问题。为我解决这个问题的是:

我相信每个微前端都将自己的样式表注入到 DOM 中,无论是否通过调用 makeStyles,我并不完全确定。您可以在此示例中看到这一点 - https://d4e2yqa5hvu3s.cloudfront.net/ 通过检查源代码并查看 head 标签 - 有两个 MuiTypography。其源代码在本文中链接。我所做的是确保材质 ui 组件/样式的导入全部一致。因此,如果您在导入映射中声明:

{
 "@material-ui/core": "<location of js>"
}

那么您的组件的所有导入都必须遵循:

import { x } from '@material-ui/core';

我还为每个样式类添加了每个微前端的唯一名称和种子(请参阅上面的文章和此处)。喜欢:

import { ThemeProvider, StylesProvider, createGenerateClassName } from '@material-ui/core';

const generateClassName = createGenerateClassName({
  disableGlobal: true,
  productionPrefix: 'foo', // defaults to 'jss'
  seed: 'bar', // defaults to ''
});
  ...
  <StylesProvider generateClassName={generateClassName}>
      <ThemeProvider theme={myTheme}>
  ...

我相信我已经缓解了任何问题(样式/传播损坏),并且页面上有关多种样式的警告现已消失,但如果有人有更多想法,我很想听听它们:)


0
投票

还需要将material-ui放置在webpack外部中。

© www.soinside.com 2019 - 2024. All rights reserved.