我正在使用lerna创建一个monorepo,其中我将具有以下结构:
root
packages
application - Our root application
components - Just some react components, that are to be used by the application
这里是a working Github with a simple example for this。
我遇到的问题是,我正在使用Material-UI及其主题功能,在应用程序根目录中,我们将拥有一个ThemeProvider:
import { ThemeProvider } from '@material-ui/styles';
//...
function App() {
return (
<ThemeProvider theme={theme}>
<MyMaterialComponent/>
</ThemeProvider>
);
}
然后在库组件中,我们使用主题makeStyles
来使用主题。
import React from 'react';
import { makeStyles } from '@material-ui/styles';
import Card from "@material-ui/core/Card";
const useStyles = makeStyles(theme => {
console.log(theme); //When this component doesn't have access to the theme, this is `{}`
return {
root: {
//color: theme.palette.primary.main //will error
}
}
});
export function MyMaterialComponent({ }) {
const classes = useStyles();
return (<Card>
<span className={classes.root}>This is some component</span>
</Card>
);
}
现在,这似乎很简单。当我们在同一程序包中全部运行此代码时,它可以正常工作。该样式功能可以访问主题。
但是,当我从另一个包(我们的应用程序包)运行时,组件库不再有权访问主题(主题只是一个空对象)。
我目前唯一知道解决该问题的方法是解决类似钩子问题的相同方法,即在应用程序中设置Webpack别名配置,以指示组件库共享同一节点模块。 (See this Github thread and the suggested solution)。
即。使用react-app-rewired和custom-cra我有一个config-overrides.js,看起来像这样:
const {
override,
addWebpackAlias,
} = require("customize-cra");
const path = require('path');
module.exports = override(
addWebpackAlias({
react: path.resolve('./node_modules/react'),
//comment out the line below to reproduce the issue
"@material-ui/styles": path.resolve("./node_modules/@material-ui/styles")
})
)
或者您可以手动管理Webpack来执行类似的操作。
所以这很好用,但这不是一个特别令人满意的解决方案。
尤其是对于像Material-UI这样的库,您希望用户能够使用您的组件库而又不会弄乱他们的webpack配置。
所以我想我在这里一定做错了-您能告诉我什么吗?
答案 0 :(得分:0)
您可以通过将@material-ui/core
依赖从devDependencies放置到库项目中的peerDependencies中来实现。就我而言,这解决了我的问题。
有关peerDependencies的更多信息:
https://classic.yarnpkg.com/en/docs/dependency-types/#toc-peerdependencies