Next + TS + styled-components 초기 설정하기
1. nexts.js + ts로 프로젝트 생성
터미널에 다음과 같이 입력합니다.
yarn create next-app --ts
2. styled-components 관련 패키지 다운로드
yarn add styled-components
yarn add -D @types/styled-components babel-plugin-styled-components
3. _document.tsx 생성 및 설정
pages 폴더 안에 _document.tsx를 생성한 뒤 다음의 코드를 삽입합니다.
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
} from "next/document";
import { ServerStyleSheet } from "styled-components";
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
render() {
return (
<Html>
<Head></Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
SSR에서 styled-component를 사용할 경우 커스터마이징이 필요합니다.
위의 코드를 추가해야 SSR 시에 styled가 헤더에 주입되서 스타일이 적용됩니다.
추가해주지 않으면 CSS가 적용되지 않고 먼저 렌더링되는 현상이 발생합니다.
4. _app.tsx 코드 수정
기존에 있는 _app.tsx를 다음과 같이 수정합니다.
import type { AppProps } from "next/app";
import { ThemeProvider } from "styled-components";
import { createGlobalStyle } from "styled-components";
const GlobalStyles = createGlobalStyle`
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
scroll-behavior: smooth;
overflow-x: hidden;
}
body {
font-size: 1.6rem;
font-family: 'Inter', 'sans-serif';
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
}
a {
text-decoration: none;
color:black;
}
ul {
list-style-type: none;
}
img{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
button{
border:none;
cursor:pointer;
&:focus{
outline:none;
}
}
input {
outline:none;
padding: 0 1.5rem;
&:focus::placeholder{
color:transparent;
}
}
`;
const theme = {
colors: {
//@ common style
mainColor: "#FF6363",
pointColor: "#304ffd",
lightblue: "#C5E2EE",
starColor: "#fd4",
},
};
export type Theme = typeof theme;
function MyApp({ Component, pageProps }: AppProps) {
return (
<ThemeProvider theme={theme}>
<GlobalStyles />
<Component {...pageProps} />
</ThemeProvider>
);
}
export default MyApp;
이 파일에서 GlobalStyles와 theme를 주입할 수 있습니다.
이 부분은 React 어플리케이션에서 styled-components를 사용할 때도 동일하게 추가하는 부분입니다.
GlobalStyles와 theme 안의 값들은 본인이 쓰는 스타일에 맞게 설정하면 됩니다.
5. .babelrc 파일 생성 및 설정
root 위치에서 .babelrc라는 이름의 파일을 생성하고 안에 다음의 코드를 삽입합니다.
{
"presets": ["next/babel"],
"plugins": [["babel-plugin-styled-components"]]
}
babel-plugin-styled-components를 플러그인으로 설정해줘야
Warning: Prop `className` did not match. Server: "sc-gsDKAQ bJpAhU" Client: "sc-bdvvtL bulXLB"
위와 같은 경고가 발생하지 않습니다.
위의 에러는 첫 페이지는 SSR로 작동하고 그 이후는 CSR로 화면을 렌더링하는 Next의 특성 때문에 발생합니다.
styled-components는 렌더링시 컴포넌트명에 해시값이 추가되어 고유한 값을 만들면서 class에 추가됩니다.
이때, 서버에서 받은 컴포넌트명 + 해시와 이후 클라이언트에서 작동하는 컴포넌트명 + 해시가 달라지면서 스타일을 불러올수 없는 문제가 발생합니다.
이 문제를 babel-plugin-styled-components 플러그인이 해결해줍니다.
6. styled-components가 잘 적용되는지 확인
이 단계까지 오셨다면 next.js, typescript, styled-component를 함께 사용할 수 있는 설정을 마치셨습니다.
잘 되는지 확인하기 위해 pages 폴더 안에 index.tsx에서 styled-components를 사용해보았습니다.
import type { NextPage } from "next";
import styled from "styled-components";
const Container = styled.div`
color: ${({ theme: { colors } }) => colors.pointColor};
text-align: center;
font-size: 24px;
`;
const Home: NextPage = () => {
return <Container>Home</Container>;
};
export default Home;
잘 적용되는 것을 볼 수 있습니다!
옵션) svg 로더 추가
웹 어플리케이션을 개발하다보면 여러 이미지, 아이콘 등이 들어가게 되는데 svg는 높은 확률로 1번 이상 들어갑니다.
그래서 나중에 svg가 들어가는 경우를 위해 미리 웹팩 설정을 추가해줍니다.
next.config.js 파일을
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
webpack: (config) => {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"],
});
return config;
},
};
module.exports = nextConfig;
다음과 같이 수정해주면 됩니다.
참고
https://velog.io/@danmin20/Next.js-Typescript-Styled-component-쉽게-구축하기
https://velog.io/@hwang-eunji/Styled-components-nextjs에서-className-오류
Author And Source
이 문제에 관하여(Next + TS + styled-components 초기 설정하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dkdlel102/Next-TS-styled-components-초기-설정하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)