material-ui 当将MUI Package 在一个库中时,样式未添加到shadow DOM中,

ufj5ltwl  于 6个月前  发布在  其他
关注(0)|答案(2)|浏览(47)

重现步骤

链接到实时示例: https://6698f74d46bade9e76f1d058--guileless-sorbet-bf347d.netlify.app/
https://github.com/MartinJaskulla/reproduction-library
https://github.com/MartinJaskulla/reproduction-library-user

  1. git clone https://github.com/MartinJaskulla/reproduction-library-user
  2. npm i
  3. npm run dev
  4. 查看错误:MUI <Button> 没有样式,因为情绪样式表被添加到了 <head> 而不是shadow DOM
  5. 在main.jsx中注解掉 Button, 并注解掉 // import {Button} from "@mui/material";
  6. Bug消失

当前行为

<Button> 在shadow DOM内部看起来像一个原生的html <button>

预期行为

<Button> 应该在shadow DOM内部看起来像一个MUI按钮。

上下文

我为公司创建了一个组件库,该库 Package 了MUI并进行了一些调整。一切都运行得非常顺畅。
对于新功能,我们需要在shadow DOM内部使用我的库,这意味着正在安装我的组件库的项目正在创建一个自定义元素,并希望在其中使用从我的库中 Package 的MUI组件。我按照文档( https://mui.com/material-ui/customization/shadow-dom/ )这样做。不知何故,样式确实被添加到了 <head> ,而不是shadow DOM。
为了重现问题,我为重现创建了一个新的库,其中我只是重新导出MUI(这是该库唯一做的事情):
https://github.com/MartinJaskulla/reproduction-library/blob/main/src/main.jsx

export * from "@mui/material";

如果我在这个新项目( https://github.com/MartinJaskulla/reproduction-library-user )中安装这个库,那么 import { Button } from "@mui/material"; 将正确的样式添加到shadow DOM,但是 import { Button } from "reproduction-library"; 将样式添加到了 <head> ,尽管两个按钮的代码应该是相同的。
对我来说,似乎只有在从 "@mui/material"; 导入时,MUI才能在shadow DOM内部工作。

你的环境

npx @mui/envinfo

System:
    OS: macOS 14.5
  Binaries:
    Node: 22.2.0 - /opt/homebrew/bin/node
    npm: 10.7.0 - /opt/homebrew/bin/npm
    pnpm: Not Found
  Browsers:
    Chrome: 126.0.6478.182
    Edge: Not Found
    Safari: 17.5

搜索关键词: shadowdom library styles emotion

kgsdhlau

kgsdhlau1#

我目前发现的情况是:
node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js 中有两行相关的代码。第一行设置了 <style> 元素将要添加到的容器,options.containershadowContainer 传递给 createCache 的:

this.container = options.container;

第二行向容器中添加了 <style> 元素:

_this.container.insertBefore(tag, before)

如果我从 "@mui/material" 导入 Button,那么这两行代码都将从 node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js 执行。如果我从 "reproduction-library" 导入 Button,那么第一行代码将在 node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js 执行,但第二行代码将在我的库包 node_modules/reproduction-library/dist/main.js 中执行。
我是如何调试这个问题的:

  • node_modules/reproduction-library/dist/main.jsnode_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js 中添加断点
  • 每次修改上面的文件后(例如 node_modules/reproduction-library/dist/main.js),删除 node_modules/.vite
  • 重启 npm run dev
  • 从调试器忽略列表中移除 node_modules:

dgsult0t

dgsult0t2#

如果我将 CacheProvider 打包到我的库中,然后从 "reproduction-library" 而不是 "@emotion/react" 导入它,问题就消失了。
我不知道这是否是推荐的方法。也许应该在某个地方记录一下?正如其他人之前所提到的,如果能有关于如何 Package MUI以构建自己的组件库的文档/示例/模板会很好。
也许这个问题可以关闭。
参考:
库中的代码:

export * from "@mui/material";
export {CacheProvider} from "@emotion/react"`

相关问题