본문 바로가기

main/Next.js

[Next.js] 기존 React 프로젝트 Next.js로 바꾸기 - 3 (TS, Styled-Component, SVG)

✏ TypeScript 적용하기

Next.js를 프로젝트를 시작할 때 TS를 적용한다.

npm i next react react-dom
npm i -D typescript @types/react @types/node

타입스크립트는 빌드 과정에서 자바스크립트로 변환되기 때문에 실제 배포될 결과물에는 포함되지 않는다.

따라서 -D 또는 --save-dev를 붙여 devDependencies에 추가하여 빌드 시에 모듈이 추가되지 않도록 한다.

 

@types/로 시작하는 라이브러리는, 라이브러리의 타입을 나타낸다.

타입이 내장되어 있는 모듈도 있지만, 그렇지 않은 경우에는 추가적으로 설치해주어야 한다.


TypeScript 사용하기

예제에서 만드는 투두리스트로 TS를 사용하는 방법을 알아본다. d.ts는 타입스크립트 코드의 타입 추론을 돕는 파일이다.

이 d.ts에 투두 아이템들의 속성들을 타입으로 만들어, types 폴더에 관련된 타입끼리 모아 관리한다.

`types/todo.d.ts`

export type TodoType = {
  id: number;
  text: string;
  color: "red" | "yellow" | "green";
  checked: boolean;
};

color의 경우 string 으로 선언해주어도 되지만, 값을 지정해줌으로써 속성을 더 명확히 한다.

 

이 TodoType을 만약 props로 컴포넌트에 전달해주게 되면, 받는 컴포넌트에서도 타입을 설정해 주어야 한다.

import { TodoType } from "../types/todo";

interface IProps {
  todos: TodoType[];
}

const TodoList: React.FC<Props> = () => {
  ...

 

 

또, 프로젝트에 필요한 색상들을 'palette'라는 파일에 미리 정리하여 사용하겠다.

`styles/palette.ts`

export default {
  red: "#FFAFB0",
  yellow: "#FCFFB0",
  green: "#E2FFAF",
  ...
};

Styled-Component 사용하기

Styled-component는 CSS-in-JS의 대표적인 라이브러리이다.

Next.js에서는 기본적으로 styled-jsx를 지원하지만, Styled-component를 사용하기 위해서는 따로 설정을 해주어야한다.

npm i styled-components
npm i @types/styled-components -D

 

Document를 확장하고 서버사이드 렌더링 과정에서 <head>에 스타일을 추가한다.

`pages/_documents.tsx`

import Document from "next/document";
import { ServerStyleSheet } from "styled-components";

export default 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();
    }
  }
  ...
}

서버사이드 렌더링 과정에서 필요한 바벨 플러그인을 추가해준다.

`.babelrc`

{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": true }]]
}

이제 코드에서 스타일드 컴포넌트를 사용할 수 있다.

vscode에서는 vscode-styled-components 익스텐션을 설치하면 색상 하이라이트를 지원받을 수 있다.

 

스타일드 컴포넌트를 사용하면 태그마다 스타일링을 할 수 있지만,

컴포넌트를 세세하게 나누지 않으면 태그가 좀 지저분해지고 알아보기 힘들다고 느낀적이 있었다.

이 책에서는 className을 유니크하게 만들어 사용하고 있다. 나도 앞으론 이렇게 해야지..

const Container = styled.div`
  width: 100%;
  
  .todo-list-header {
    ...
  }
`;

const TodoList: React.FC<IProps> = ({ todos }) => {
  return (
    <Container>
      <div className="todo-list-header">
        ...

↑ 이거 실제로 사용해보니, className이 좀 더 보기편한건 사실이지만

좀 귀찮은 경우 위처럼 className 대신 그냥 상속된 태그네임으로 써버리는 경우가 (무의식적으로) 생겨서,

이런 경우 추후에 유지보수가 어려워질 듯. 귀찮아도 태그네임으로 사용하지 않게 더 조심하면서 사용해야겠다.

 

또, typescript에서 사용하려다보니 HTML 태그에 존재하지 않는 속성을 사용할수가 없는 것 같다.. ㅠㅠ

그래서 styled-component에 상탯값을 전달하기 위해 저 부분은 className을 삭제하고 styles.div``로 선언 후 사용했다.


 SVG 사용하기

inline SVG

코드가 굉장히 길지만 어쨌든 이 embed 코드를 사용하면 그냥 붙여넣으면 바로 이미지가 나온다.

위 사이트는 https://iconmonstr.com/ <임

 

 

next/image 에서 사용

우선 라이브러리를 설치하고 .babelrc에 svg를 사용하겠다는 설정을 해 준다.

npm i babel-plugin-react-svg -D

.babelrc

{
    ...,
    "plugins": [
      ...
      "inline-react-svg"
    ]
}

types/image.d.ts

declare module "*.svg";

타입을 정의해준 뒤 실제 코드에서는

import Image from "next/image";

  ...
  return (
    <Image src="svg파일주소" alt="" width="" ... />
  );

이렇게 사용하면 잘 나온다!

 

 

react-icons

npm install react-icons --save

패키지를 설치하고 사이트에서 아이콘을 찾아서 사용하면 되는데

각각의 메뉴에서 찾아서 쓰면 해당 아이콘이 어느 폴더에 속해있는지 바로 알 수 있어 편하지만

그게 아니라 전체를 검색하면 해당 아이콘이 어느 폴더에 있는 애인지 바로 알려주지는 않고 앞에 붙은 이름으로 유추해서 찾아야 하는 것 같다. 내가 못 찾은거면 광광...우럭...

이렇게 쓸 바에야 그냥 svg 쓰는게 낫겠다는 생각이 든다. 괜히 쓰지않는 아이콘을 다 설치할 필요도 없고.