我正在使用Material-ui构建一个next.js应用程序。
我尝试将Material-ui应用到我的项目中。
我从官方GitHub页面复制了_app.js,_document.js,theme.js
等文件。
所有文件都在同一个pages
文件夹中。
但是当运行应用程序时,出现了一个我不理解的错误。
TypeError: (0 , _material_ui_core_styles__WEBPACK_IMPORTED_MODULE_0__.createTheme) is not a function
at Object../pages/theme.js (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\pages\_document.js:193:84)
at __webpack_require__ (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\webpack-runtime.js:25:42)
at Object../pages/_document.js (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\pages\_document.js:32:64)
at __webpack_require__ (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\webpack-runtime.js:25:42)
at __webpack_exec__ (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\pages\_document.js:395:52)
at C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\pages\_document.js:396:321
at Function.__webpack_require__.X (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\webpack-runtime.js:108:21)
at C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\pages\_document.js:396:47
at Object.<anonymous> (C:\Users\micor\OneDrive\Documents\React\Proyectos React\nextMaterial\my-app\.next\server\pages\_document.js:399:3)
at Module._compile (node:internal/modules/cjs/loader:1108:14)
我将在下面留下代码
_document.js
import * as React from 'react';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/styles';
import createEmotionServer from '@emotion/server/create-instance';
import theme from './theme';
const getCache = () => {
const cache = createCache({ key: 'css', prepend: true });
cache.compat = true;
return cache;
};
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
{/* PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with static-site generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
const cache = getCache();
const { extractCriticalToChunks } = createEmotionServer(cache);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
// Take precedence over the CacheProvider in our custom _app.js
enhanceComponent: (Component) => (props) =>
(
<CacheProvider value={cache}>
<Component {...props} />
</CacheProvider>
),
});
const initialProps = await Document.getInitialProps(ctx);
const emotionStyles = extractCriticalToChunks(initialProps.html);
const emotionStyleTags = emotionStyles.styles.map((style) => (
<style
data-emotion={`${style.key} ${style.ids.join(' ')}`}
key={style.key}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.css }}
/>
));
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
...emotionStyleTags,
],
};
};
_app.js
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider } from '@material-ui/core/styles';
import { CacheProvider } from '@emotion/react';
import CssBaseline from '@material-ui/core/CssBaseline';
import createCache from '@emotion/cache';
import theme from './theme';
export const cache = createCache({ key: 'css', prepend: true });
export default function MyApp(props) {
const { Component, pageProps } = props;
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<CacheProvider value={cache}>
<Head>
<title>My page</title>
<meta name="viewport" content="initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</CacheProvider>
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
pageProps: PropTypes.object.isRequired,
};
最后的theme.js文件
import { createTheme } from '@material-ui/core/styles';
import { red } from '@material-ui/core/colors';
// Create a theme instance.
const theme = createTheme({
palette: {
primary: {
main: '#556cd6',
},
secondary: {
main: '#19857b',
},
error: {
main: red.A400,
},
background: {
default: '#fff',
},
},
});
export default theme;