이번에 새로운 사이드프로젝트를 진행하면서 기술 스택들이 정해졌고, 해당 스택들을 사용해서 프로젝트를 생성하려고 한다.
react와 scss로 작업해본 경험이 있어서 이번엔 크게
next.js (react를 했으니 그래도 좀 수월하지 않을까라는 생각) 와 typescript, styled-component를 사용해보려고 한다.
next 프로젝트 생성하기 with Typescript
$ npx create-next-app --example with-typescript [프로젝트 이름]
typescript와 같이 next프로젝트를 생성해주는 명령어이다.
실행이 끝나면 cd 를 사용해서 프로젝트로 이동해준다.
$ npm install
npm install를 사용해서 필요한 패키지들을 설치해준다.
설치가 다 되면 npm run dev를 입력 후 localhost:3000 접속해서 잘 실행 되는지 확인한다. 포트는 3000번이다.
$ npm run dev
프로젝트 폴더 구조는 다음과 같이 구성했다.
처음에 접속하게 되면 pages/index.tsx 페이지를 볼 수 있다. 각 페이지마다 접속 경로는 다음과 같다
/ => pages/index.tsx
/about => pages/about.tsx
/users => pages/users/index.tsx
/users/id => pages/users/[id].tsx
public 폴더에는 이미지나 font등의 파일을 넣을 예정이다.
src 폴더에는 component나 css 등의 파일을 넣을 예정이다.
Styled-Component 적용
$ npm i styled-components styled-normalize
$ npm i -D @types/styled-components
두 개의 명령어를 사용해서 styled-component를 설치해준다.
위에는 styledComponent설치하는 명령어이고,
아래는 typescript를 적용하면 styled-component를 인식하지 못하기 때문에 type을 정의해놓은 라이브러리도 같이 설치해줘야한다.
src/styles 폴더 안에 3개의 파일을 생성해준다.
global-style.ts 파일은 전역 스타일을 설정하는 부분
styled.d.ts 파일은 theme파일에 들어갈 변수들의 타입을 정하는 부분
theme.ts 파일은 공통적으로 사용할 스타일을 지정하는 부분
- global-style.ts
전역에 적용할 스타일을 적어주면 된다. 아래의 코드는 모든 html에 font크기는 20px, min-width는 320px으로 설정한다.
import { createGlobalStyle } from "styled-components";
import { normalize } from "styled-normalize";
export const GlobalStyle = createGlobalStyle`
${normalize}
html {
box-sizing: border-box;
font-size: 20px;
min-width: 320px;
}
a { cursor: pointer; text-decoration: none; }
`;
- styled.d.ts
theme.ts에서 사용할 변수들의 타입을 지정해준다.
import "styled-components";
declare module "styled-components" {
export interface DefaultTheme {
colors: {
black: string;
white: string;
orange: string;
};
}
}
- theme.ts
styled.d.ts에서 정의한 타입에 맞춰서 theme을 정의해준다.
import { DefaultTheme } from "styled-components";
export const theme: DefaultTheme = {
colors: {
black: "#1e1f1d",
white: "#ffffff",
orange: "#eb7952",
},
};
이제 위에서 정의한 스타일과 theme를 page에 적용하려고한다.
Next.js에서는 페이지가 실행되면 가장 먼저 App컴포넌트가 실행된다. 따로 만들어주지 않으면 내장된 로직이 실행된다. 그래서 모든 페이지에 스타일을 적용시켜주기 위해서는 App컴포넌트를 생성해줘야한다.
pages폴더 안에 _app.tsx파일을 생성한 후, 전역 스타일과 테마로 감싸준 코드를 넣어준다.
/pages/index.tsx
import type { AppProps } from "next/app";
import { ThemeProvider } from "styled-components";
import { GlobalStyle } from "../styles/global-style";
import { theme } from "../styles/theme";
export default function App({ Component, pageProps }: AppProps) {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<Component {...pageProps} />
</ThemeProvider>
);
}
.babelrc 파일 추가
이 파일을 추가하지 않으면 스타일이 적용되기 전에 렌더링되는 현상이 발생한다. 그래서 추가해줘야한다.
$ npm i -D babel-plugin-styled-components
최상위 디렉토리에 .babelrc 파일을 추가해주고 다음과 같은 내용을 넣어준다.
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": false
}
]
]
}
_document.tsx 파일 추가
next에서 styled component를 사용하면 css 로딩이 늦게 되서 깜빡이는 현상이 발생한다.
따라서 _document.tsx파일에 css를 미리 적용해야한다. _document.tsx 파일은 pages폴더 내부에 존재하는 모든 페이지에 global한 설정값을 줄 수 있는 파일이다.
최상위 디렉토리에 _document.tsx 파일을 추가해주고 다음과 같은 내용을 넣어준다.
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
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();
}
}
}
'개발 공부 > Next JS' 카테고리의 다른 글
[노마드코더] NextJS 시작하기 #4 (0) | 2022.04.09 |
---|---|
[노마드코더] NextJS 시작하기 #3 (0) | 2022.04.08 |
[노마드코더] NextJS 시작하기 #2 (0) | 2022.04.07 |
[노마드코더] NextJS 시작하기 #1 (0) | 2022.03.22 |
[Next] NextJS의 getInitialProps, getStaticProps, getStaticPaths, getServerSideProps 함수 (0) | 2022.03.20 |