Next.Js 12 + MUI 5(Material UI) 새 튜토리얼
추상적인
SSR
프레임워크에는 Next.js
, Nuxt
, Sveltekit
등 가장 가까운 프레임워크는 react
기반의 Next.js
일 것입니다.본 보도에서는
Next.js
에 가장 반응이 좋은 컴포넌트 라이브러리 중 하나인 MUI
을 적용하는 가장 최신 방법을 소개하고 싶다.기존의
@mui/styles
패키지를 통해 적용하는 방법은 react 18
의 호환성 문제로 deprecatedMUI의 레거시 스타일링 솔루션: https://mui.com/system/styles/basics/
시작하기
원하는 프로젝트 폴더에
Next.js TypeScript
프로젝트를 생성합니다.단말기
pnpm create next-app . --typescript
MUI
관련 설치 패키지단말기
pnpm add -S @emotion/cache @emotion/react @emotion/server @emotion/styled @mui/icons-material @mui/material
createEmotionCache
드디어 모듈인 emotionCache.ts
를 lib
폴더에 생성메모
<head/>
의 가장 최상단에 <meta>
태그를 생성하고 이를 insertionPoint
로 진단한다. MUI
로 개발 가능한 이점을 가지게 된다. lib/emotionCache.ts
import createCache from '@emotion/cache';
const isBrowser = typeof document !== 'undefined';
const createEmotionCache = () => {
let insertionPoint;
if (isBrowser) {
const emotionInsertionPoint = document.querySelector(
'meta[name="emotion-insertion-point"]'
) as HTMLElement;
insertionPoint = emotionInsertionPoint ?? undefined;
}
return createCache({ key: 'mui-style', insertionPoint });
};
export default createEmotionCache;
lib
폴더에 theme.ts
도 생성메모
lib/theme.ts
import { createTheme } from '@mui/material/styles';
import { indigo } from '@mui/material/colors';
const theme = createTheme({
palette: {
primary: {
main: indigo.A400,
},
},
});
export default theme;
_app.tsx
파일을 다음과 같이 수정페이지/_app.tsx
import * as React from 'react';
import Head from 'next/head';
import { ThemeProvider } from '@mui/material/styles';
import { CacheProvider } from '@emotion/react';
import CssBaseline from '@mui/material/CssBaseline';
import theme from '../lib/theme';
import createEmotionCache from '../lib/emotionCache';
import type { NextPage } from 'next';
import type { AppProps } from 'next/app';
import type { EmotionCache } from '@emotion/react';
type AppPropsWithCache = AppProps & {
Component: NextPage;
emotionCache?: EmotionCache;
};
const clientSideEmotionCache = createEmotionCache();
const MyApp = ({
Component,
emotionCache = clientSideEmotionCache,
pageProps,
}: AppPropsWithCache) => {
return (
<CacheProvider value={emotionCache}>
<Head>
<meta name='viewport' content='initial-scale=1, width=device-width' />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</CacheProvider>
);
};
export default MyApp;
_document.tsx
뒤 파일을 생성한 다음과 함께 작성메모
_Document.getInitialProps
은 _app
이 대신 _document
에 상속되고 static 으로 생성됨_Document.getInitialProps = async (ctx: DocumentContext): Promise<DocumentInitialProps> => {...}
const cache = createEmotionCache();
styles fragment
은 app
과 page
의 포켓몬이 복제된다.styles: [...React.Children.toArray(initialProps.styles), ...emotionStyleTags],
참고링크: https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html);
생성기
서버
서버에러
친구
페이지/_document.tsx
import * as React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import createEmotionServer from '@emotion/server/create-instance';
import theme from '../lib/theme';
import createEmotionCache from '../lib/emotionCache';
import type { DocumentContext, DocumentInitialProps } from 'next/document';
export default class _Document extends Document {
render() {
return (
<Html lang='ko'>
<Head>
<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'
/>
<meta name='emotion-insertion-point' content='' />
{this.props.styles}
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
_Document.getInitialProps = async (ctx: DocumentContext): Promise<DocumentInitialProps> => {
const originalRenderPage = ctx.renderPage;
const cache = createEmotionCache();
const { extractCriticalToChunks } = createEmotionServer(cache);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />;
},
});
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: [...React.Children.toArray(initialProps.styles), ...emotionStyleTags],
};
};
index.tsx
를 다음과 함께 작성페이지/index.tsx
import { Button } from '@mui/material';
import type { NextPage } from 'next';
const Home: NextPage = () => {
return (
<main
style={{
width: '100vw',
height: '100vh',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div>
<header>
<h1>MUI5 + Next.js 12</h1>
</header>
<section>
<Button variant={'contained'}>Hello MUI</Button>
</section>
</div>
</main>
);
};
export default Home;
시사
➕ Stackblitz 샘플
결론
본 포스팅에서는
MUI 5
를 Next.Js 12
에 적용하는 최신 방법을 소개했습니다. (2022년 8월 기준)react 18
이면서 조합이 존재하는 방법보다 시야할 부분이 위장건이나 여전히 참조가 많은 조합을 선호하는 트렌트 입고는 가장 할 수 있는 SSR 프레임워크 + UI 라이브러리인 Next.Js
+ MUI
는 킹 이용될 것이다.추천하는 React UI Framework 중 하나인 Mantine을 소개하면서 글을 마무리 짓고자 합니다.
만타인: https://mantine.dev/
Reference
이 문제에 관하여(Next.Js 12 + MUI 5(Material UI) 새 튜토리얼), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/soom/nextjs-12-mui-5-material-ui-tutorial-hoh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)