我有一个自定义 MUI 5 组件库 NPM 包,它导出一些使用 MUI 5 构建的基本组件,导出 theme 文件并将主题提供程序包装到可重用组件中,如下所示:
import { ThemeProvider } from 'styled-components';
import { StyledEngineProvider } from '@mui/material/styles';
import { theme as defaultTheme } from './theme';
function CustomThemeProvider(props: {
theme: any;
children: JSX.Element[];
}): JSX.Element {
const { theme = defaultTheme, children } = props;
return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</StyledEngineProvider>
);
}
export default CustomThemeProvider;
但是,当我尝试使用此自定义主题提供程序以及使用此共享库的项目中的组件时,主题根本不应用。这种方法确实适用于 MUI 4,但当时没有情感层,并且设置要简单得多。
我已将所有这些添加到共享组件包的对等依赖项中,以保持引用完整。
"peerDependencies": {
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.2.4",
"@mui/lab": "^5.0.0-alpha.60",
"@mui/styles": "^5.2.3",
"@mui/material": "^5.2.4",
"@mui/styled-engine-sc": "^5.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"styled-components": "^5.3.3"
},
但这没有什么区别。
欢迎任何如何使其工作的想法,或任何其他允许共享 MUI 5 组件库/主题工作的方法!
不确定这是否是相同的情况,但就我而言,这是使用
npm link
进行本地开发的问题。
注意: 如果
@mui
未列为组件包的 peerDependency
,您也可能会遇到此问题。
TLDR: 如果您的共享组件库包安装了自己的
@mui
副本(即 /node_modules/pkg/node_modules/@mui
),那么您的共享 ThemeProvider 将无法工作。
我有一个非常相似的设置,有一个共享的 npm 包 (
@my/custom-components
),并以 MUI 作为对等依赖项。在消费应用程序中,我使用了npm link @my/custom-components
。
使用链接的问题是它会创建一个指向本地包的符号链接,这并不代表最终的构建。发布
@my/custom-components
时,仅包含 package.json
和 dist/
文件夹。但在我的本地计算机上,它包含所有源文件,包括node_modules
文件夹。
通常,具有peerDependency的包不会有自己的子
node_modules
文件夹,以确保它使用主机应用程序的依赖项。但通过此本地设置,@my/custom-components
正在配置自己的 MUI 副本,而不是主机应用程序的 MUI:
// When using npm link
host-app
├── node_modules
│ ├── @my/custom-components
│ │ ├── dist
│ │ ├── node_modules
│ │ │ └── @mui/material-ui <== conflicting copy
│ │ └── package.json
│ └── @mui/material-ui <== host copy
├── src
└── package.json
// When installed normally
host-app
├── node_modules
│ ├── @my/custom-components
│ │ ├── dist
│ │ └── package.json
│ └── @mui/material-ui <== only copy
├── src
└── package.json
为了解决这个问题,我:
npm install
)@my/custom-components
(npm pack
)host-app/node_modules/@my/custom-components
。我在使用 Vite 和 MUI 5 构建的组件上遇到了类似的问题。在本地测试中,该组件没有选择正确的主题。这是由于 @elstgav 发现的问题,npm 链接和 nod_modules 存在于链接的包文件夹中。
我使用Vite的别名解析配置(与Rollup的解析相同)来指向正确的node_modules。
vite.config.js:
resolve: {
alias: [
{
find: /^(@mui\/[\w-]+)/,
replacement: path.resolve(__dirname, "node_modules/$1"),
},
],
},
我找到了解决方案,我所做的是,
使用汇总的自定义构建配置创建主题项目。在他们那里我添加了 @mui/ 作为外部包。然后导出 mui5 主题提供程序。
然后在消费者项目中消费它。消费者项目需要有 mui5 作为依赖项。很简单,我们正在共享 mui5。
示例汇总配置==>
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
const packageJson = require('./package.json'); // eslint-disable-line @typescript-eslint/no-var-requires
export default {
input: 'src/index.ts',
external: [
'react',
'react-dom',
'prop-types',
'@emotion/react',
'@emotion/styled',
'@mui/lab',
'@mui/icons-material',
'@mui/material',
'@mui/material/styles',
'@mui/styles',
],
output: [
{
file: packageJson.main,
format: 'cjs',
sourcemap: true,
},
{
file: packageJson.module,
format: 'esm',
sourcemap: true,
},
],
plugins: [
resolve(),
commonjs(),
typescript({ useTsconfigDeclarationDir: true }),
],
};
我找到了解决办法。添加外部主题提供程序是我从 MUI4 转换而来的大材小用。
在 MUI 5 中,唯一需要的是共享主题文件。因此,将主题文件放在共享组件库中,并将其导入到使用它的项目中,但将主题提供程序保留在所有三个代码库中本地。