Next.js 14 App router with Ant Design 5 & Styled-Components
์นดํ ๊ณ ๋ฆฌ | ๊ธฐ์ |
---|---|
ํ๊ทธ | |
์์ ์ผ | Jan 3, 2024 |
์์ฑ์ผ | Dec 18, 2023 |
Ant Design 5
์ Styled-Components
๋ฅผ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํฉ๋๋ค.์ค์น
- Engine:
Node 18.19.0
- Package Manager:
yarn 1.22.19
1. Next.js 18 ์ค์น
# node v.18.19.0 ์์ ์คํ
npx create-next-app@latest
# next v14.0.4 ์ค์น๋จ.
์ฐธ๊ณ : https://nextjs.org/docs/getting-started/installation
2. antd ์ค์น
yarn add antd styled-components @ant-design/cssinjs
3. ํ์ธ
styled-component ๋์ ํ์ธ์ ์ํด ๊ฐ๋จํ๊ฒ /app/pages
๊ฒฝ๋ก์ ๊ธ์ ์์์ ์คํ์ผ๋ง ํด๋ณด์๋ค.
// src/app/page.tsx
'use client';
import styled from 'styled-components'
// hotpink ๊ธ์์ ์ ์ฉ
const CustomEl = styled.h1`
color: hotpink;
`
export default function Home() {
return (
<main>
<CustomEl>
Get started by editing
<code>src/app/page.tsx</code>
</CustomEl>
</main>
)
}
์ ์ฉ์ ๋์ง๋ง css-in-js ๋ ๋ฐํ์์์ ์คํ์ผ์ด ์์ฑ๋์ง ์์ ์๋ก๊ณ ์นจ ์ ๊น๋นก์์ด ๋ฐ์ํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ๋ํ Antd ํ ๋ง ํ ํฐ์ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Registry๋ฅผ ์ ์ฉํด์ผํ๋ค.
ezgif-3-8fa65afe9e.gif
Theme ๋ฐ Registry ์ถ๊ฐ
1. Theme ์์ฑ
// src/themes/base.ts
const baseTheme = {
token: {
fontFamily: 'Arial',
colorPrimary: 'hotpink',
//...
},
components: {
//...
},
};
export default baseTheme
2. Registry ์์ฑ
-
Styled-Components Registry ์์ฑ (๊ฒฝ๋ก:
src/providers/StyledComponentsRegistry.tsx
)// src/providers/StyledComponentsRegistry.tsx 'use client' import { ReactNode, useState } from 'react' import { useServerInsertedHTML } from 'next/navigation' import { ServerStyleSheet, StyleSheetManager, ThemeProvider } from 'styled-components' const StyledComponentsRegistry = ({ children, }: { children: ReactNode }) => { const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()) useServerInsertedHTML(() => { const styles = styledComponentsStyleSheet.getStyleElement() styledComponentsStyleSheet.instance.clearTag() return <>{styles}</> }) if (typeof window !== 'undefined') return <>{children}</> return ( <StyleSheetManager sheet={styledComponentsStyleSheet.instance}> {children} </StyleSheetManager> ) } export default StyledComponentsRegistry;
์ฐธ๊ณ : https://nextjs.org/docs/app/building-your-application/styling/css-in-js#styled-components
-
Antd Registry ์์ฑ (๊ฒฝ๋ก :
src/providers/AntdRegistry.tsx
)// src/providers/AntdRegistry.tsx 'use client'; import { StyleProvider, createCache, extractStyle } from '@ant-design/cssinjs'; import { ConfigProvider } from 'antd'; import { useServerInsertedHTML } from 'next/navigation'; import { useState } from 'react'; import baseTheme from '@/themes/base'; const AntdRegistry = ({ children }: { children: React.ReactNode }) => { const [cache] = useState(() => createCache()); useServerInsertedHTML(() => ( <style dangerouslySetInnerHTML= id='antd'></style> )); return ( <StyleProvider cache={cache}> <ConfigProvider theme={baseTheme}> {children} </ConfigProvider> </StyleProvider> ); }; export default AntdRegistry
์ฐธ๊ณ : https://ant.design/docs/react/use-with-next#using-app-router
-
Registry ์ ์ฉ
// src/app/layout.tsx import type { Metadata } from 'next' import { ReactNode } from 'react' import AntdRegistry from '@/providers/AntdRegistry' import StyledComponentsRegistry from '@/providers/StyledComponentsRegistry' export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app', } export default function RootLayout({ children, }: { children: ReactNode }) { return ( <html lang="en"> {/* Antd Registry ์ ์ฉ */} <AntdRegistry> {/* ํ ๋ง ์ฌ์ฉ์ ์ํ์ฌ AntdRegistry ์๋์ StyledComponentRegistry๋ฅผ ๋ฃ์๋ค. */} <StyledComponentsRegistry> <body>{children}</body> </StyledComponentsRegistry> </AntdRegistry> </html> ) }
-
ํ์ธ
์๋ก๊ณ ์นจ ์ ๊น๋นก์์ด ์ฌ๋ผ์ง์ ํ์ธ ๊ฐ๋ฅํ๋ค.
๐ย ant-design ์์ ์ ๊ณตํ๋ ์์ ์์ค์ฝ๋
Styled-components์์ Antd ํ ๋ง ์ฌ์ฉ
styled-component ์ด์ฉ ์ antd ํ ๋ง ๊ฐ์ ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด ์ค์ ํ๋ฉด ๋๋ค.
1. ThemeProvider ์ถ๊ฐ
// src/providers/StyledComponentsRegistry.tsx
'use client'
//...์๋ต
// antd theme ์ถ๊ฐ
import { theme } from "antd";
const StyledComponentsRegistry = ({
children,
}: {
children: ReactNode
}) => {
// token ์ด์ฉ์ ์ํด hook ํธ์ถ
const { token } = theme.useToken();
//...์ค๋ต
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{/* Antd ํ
๋ง ํ ํฐ ์ ์ฉ */}
<ThemeProvider theme=>
{children}
</ThemeProvider>
</StyleSheetManager>
)
}
export default StyledComponentsRegistry;
2. Theme ํ ํฐ ์ ์ฉ
// src/app/page.tsx
'use client';
import styled from 'styled-components'
const CustomEl = styled.h1`
&&& {
color:${({ theme })=> theme.antd?.colorPrimary};
}
`;
export default function Home() {
return (
<main>
<CustomEl>
Get started by editing
<code>src/app/page.tsx</code>
</CustomEl>
</main>
)
}
« Gulp๋ฅผ ์ด์ฉํ ์ ์ HTML ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ถ
Javascript module system (CommonJS, ES Modules) »