我将我的服务器端渲染(SSR)工作应用程序迁移到MUI版本5。我跟踪了official procedure,但是当我禁用JavaScript时,我收到了一个原始的HTML页面(没有CSS)。你可以看到它here(对不起,如果它的下降;我经常重新部署以进行测试)。
1.运行codemod(v5.0.0/preset-safe和link-underline-hover)
1.将makeStyles调用更改为使用tss-react
1.根据MUI example with Next.js修改了我的 _app 和 _document 文件
我推出了官方的SSR Next.js implementation。它表明它也不起作用。
有关详细信息,以下是我的项目中的关键文件:
_app.js
import * as React from 'react';
import Head from 'next/head';
import {ThemeProvider} from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import {CacheProvider} from '@emotion/react';
import theme from '../components/theme';
import createEmotionCache from "../lib/createEmotionCache";
import {StyledEngineProvider} from '@mui/material/styles';
import {ApolloProvider} from "@apollo/client";
import {SessionProvider} from "next-auth/react"
import {appWithTranslation} from "next-i18next";
import {useApollo} from "../apollo/client";
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
//followed example: https://github.com/mui/material-ui/tree/master/examples/nextjs
function App(props) {
const {Component, emotionCache = clientSideEmotionCache, pageProps} = props;
const apolloClient = useApollo(pageProps)
return (
<CacheProvider value={emotionCache}>
<StyledEngineProvider injectFirst>
<ApolloProvider client={apolloClient}>
<SessionProvider session={pageProps.session}>
<Head>
<meta name="viewport" content="initial-scale=1, width=device-width"/>
<title>WeAlly</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width"/>
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png"/>
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png"/>
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png"/>
<link rel="manifest" href="/images/site.webmanifest"/>
</Head>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline/>
<Component {...pageProps} />
</ThemeProvider>
</SessionProvider>
</ApolloProvider>
</StyledEngineProvider>
</CacheProvider>
);
}
export default appWithTranslation(App);
_document.js
import * as React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import createEmotionServer from '@emotion/server/create-instance';
import theme from '../components/theme';
import createEmotionCache from "../lib/createEmotionCache";
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="shortcut icon" href="/static/favicon.ico" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com"/>
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;700&display=swap"
rel="stylesheet"/>
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,600;1,400&display=swap"
rel="stylesheet"/>
<link rel="stylesheet"
href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap"
media="screen"/>
{/* Inject MUI styles first to match with the prepend: true configuration. */}
{this.props.emotionStyleTags}
</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) => {
const originalRenderPage = ctx.renderPage;
// You can consider sharing the same emotion cache between all the SSR requests to speed up performance.
// However, be aware that it can have global side effects.
const cache = createEmotionCache();
const { extractCriticalToChunks } = createEmotionServer(cache);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) =>
(function EnhanceApp(props) {
// console.log( 'enhancing app with cache: ', cache )
return <App emotionCache={cache} {...props} />;
}),
});
const initialProps = await Document.getInitialProps(ctx);
// This is important. It prevents emotion from rendering invalid HTML.
// See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html);
// console.log('emotion style count: ', emotionStyles.styles.length)
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,
emotionStyleTags,
};
};
**package.json**
{
"name": "we-ally-org",
"version": "1.0.0",
"scripts": {
"dev": "next",
"back": "node ./server/starter.js",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@apollo/client": "^3.4.17",
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@google/maps": "^1.1.3",
"@hapi/iron": "6.0.0",
"@mui/icons-material": "^5.5.1",
"@mui/material": "^5.5.2",
"@mui/styles": "^5.5.1",
"@next-auth/mongodb-adapter": "^1.0.3",
"@next/bundle-analyzer": "^11.1.0",
"@prisma/client": "2.16.1",
"apollo-server-micro": "^3.5.0",
"axios": "^0.21.1",
"body-parser": "^1.19.0",
"classnames": "^2.3.1",
"cookie": "^0.4.1",
"cors": "^2.8.5",
"deepmerge": "4.2.2",
"ejs": "^3.1.6",
"express-graphql": "^0.12.0",
"express-jwt": "^6.0.0",
"express-session": "^1.17.2",
"google-map-react": "^2.1.9",
"graphql": "^15.5.1",
"graphql-tools": "^8.1.0",
"graphql-ws": "^5.4.0",
"http-proxy": "^1.18.1",
"image-type": "^4.1.0",
"jodit-react": "^1.1.1",
"jsonwebtoken": "^8.5.1",
"linkify-react": "^3.0.4",
"linkifyjs": "^3.0.5",
"lodash": "^4.17.21",
"micro": "^9.3.4",
"moment": "^2.29.1",
"mongodb": "^4.4.1",
"next": "12",
"next-auth": "^4.3.1",
"next-compose-plugins": "^2.2.1",
"next-i18next": "^8.5.1",
"node-fetch": "^3.0.0",
"passport": "^0.4.1",
"passport-facebook": "^3.0.0",
"pino": "^6.11.3",
"prop-types": "^15.6.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-ga": "^3.3.0",
"react-image-gallery": "^1.2.7",
"react-moment": "^1.1.1",
"react-player": "^2.9.0",
"react-share": "^4.4.0",
"react-use": "^17.2.4",
"sanitize-html": "^2.4.0",
"subscriptions-transport-ws": "^0.9.19",
"tss-react": "^3.6.0"
},
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.15.5",
"@emotion/server": "^11.4.0",
"babel-plugin-styled-components": "^2.0.6",
"eslint": "8.11.0",
"eslint-config-next": "12.1.0"
}
}
另外,一个依赖库被破坏:react-image-gallerydisplays incorrectly自从升级以来,但我仍然没有深入研究。
4条答案
按热度按时间t0ybt7op1#
我的问题是React 18。在package.json中恢复到React 17\
dgtucam12#
这是一个Next.js问题,自12.1.7-canary.4及更高版本以来已经解决。
cxfofazt3#
我解决了这个问题与加载启动画面时,启动画面被摧毁一切正常,样式完全加载an article about splash screen in nextjs
ibps3vxo4#
今天,我一直在努力解决我这边的这个问题,我找到了解决方案。你应该从应用中删除你的
StyledEngineProvider
,并修改你的情绪缓存为:我以前不明白StyledEngineProvider在做什么,但它改变了CSS顺序,并将MUI样式添加到头部的顶部,但如果你在缓存解决方案中添加prepend=true,你就不再需要它了。看这个链接。