Я использую lerna для создания монорепо, где у меня будет такая структура:
root
packages
application - Our root application
components - Just some react components, that are to be used by the application
Вот рабочий Github с простым примером для этого .
Проблема, с которой я столкнулся, заключается в том, что я использую 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>
);
}
Теперь это кажется довольно простым. Когда мы запускаем этот код в одном пакете, он работает нормально. Эта функция стилей имеет доступ к теме.
Но когда я работаю из другого пакета (нашего пакета приложения), библиотека компонентов больше не имеет доступа к теме (тема - просто пустой объект).
Единственный способ, которым я в настоящее время знаю, как решить эту проблему, - это то же самое, что я решил аналогичную проблему с перехватами, которая заключается в настройке конфигурации псевдонима веб-пакета в моем приложении, чтобы указывать библиотеке компонентов использовать один и тот же узел модуль. ( См. Эту ветку Github и предлагаемое решение ).
т. с использованием response-app-rewired и customize-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")
})
)
или вы можете управлять своим веб-пакетом вручную, чтобы сделать аналогичную вещь.
Так что это прекрасно работает, но это не особенно удовлетворительное решение.
Специально для такой библиотеки, как Material-UI, вы хотите, чтобы пользователи могли использовать вашу библиотеку компонентов, не мешая им настраивать веб-пакеты.
Так что я полагаю, что я, должно быть, здесь что-то делаю не так - можете мне сказать, что?