Next - 활용

유원근·2020년 12월 13일

Next.js 후루룩

목록 보기
2/2

Next프로젝트에서 컴포넌트를 만드는 방법은 react와 동일합니다.

위 모양을 가진 컴포넌트를 만들어줄 것인데, logo이미지를 불러와야 겠죠?

이미지파일 사용하기

먼저 next에서는 아래와 같이 이미지를 불러올 수 있는 기능을 제공해주고 있습니다.

import Image from "next/image";
export default function Header() {
  return (
    <>
    	<Image src='/' width='' height='' />
    </>
  );
}

next에서 제공하는 image는 next프로젝트 진행시 정적파일들을 모아놓는 경로인 root디렉토리의 public폴더로부터 경로를 입력받는데, 저는 이렇게 image를 사용하면 여러모로 불편함이 느껴져서 next-images라는 라이브러리를 이용해 image를 사용해주도록 할 것입니다.

next-images

일반 React프로젝트시 이미지를 불러와서 사용해주던

import LOGO from "../../public/img/logo.png";

위와 같은 방법으로 진행시 에러가 출력되는 이유는 빌드시 이미지파일을 빌드시 해석하지 못하기 때문인데 이를 해결하기 위해서는, 이미지를 읽어주는 webpack-module이 필해집니다., 각각 확장자에 맞는 이미지loader를 사용하는것보다 next-images를 사용하되면 간단하게 next프로젝트에서 image를 불러와 사용할 수 있습니다.
공식문서

yarn add next-images

설치가 완료되었다면, webpack을 커스텀으로 설정해 주어야 합니다.
next의 기본설정을 유지시켜주어야 하기 때문에, 조금 어렵게 느껴질 수도 있지만, 아주 쉽게 적용시켜줄 수 있습니다.
root 경로상에 next용 Webpack설정파일인 next.config.js 파일을 생성해준뒤, 아래와 같이 입력해준다면 이미지를 사용할 수 있습니다.

const withImages = require('next-images')
module.exports = withImages({
  webpack(config, options) {
    return config
  }
})

커스텀 웹팩설정

next.config.js

일단 next.config.js 파일은 next프로젝트에서 webpack설정을 커스텀 해줄 수 있는 파일이라는 것을 알고 있습니다.
하지만, Webpack을 통해 번들링을 해줄때 과연 next-images만 사용하게 될까요?
당장만 생각해 보더라도 추후에 bundle-analyzer를 통해 빌드시 불필요한 파일들을 살펴보아야 하기때문에 추가해주어야 하는 옵션들이 상당히 많을 것입니다.

이를 해결하기 위해 여러가지 플러그인들을 쉽게 적용시킬수 있는 라이브러리인 next-compose-plugins을 사용해 주도록 하겠습니다.
설치를 진행한뒤 기본 사용법은 다음과 같습니다.

const withPlugins = require('next-compose-plugins');
 
module.exports = withPlugins([...plugins], nextConfiguration);

withPlugins로 next-compose-plugins를 실행해 주는데, 첫번째 인자로 적용시킬 플러그인들을 배열형태로 넣어주고 두번째 인자로 webpack의 설정을 넣어주면 됩니다.
같은 방식으로 next-images도 넣어주고 추가적으로 미리 @next/bundle-analyzer도 설치를 통해 적용할 수 있도록 미리 여러가지 플러그인을 설정해 주도록 하겠습니다.

const withImages = require("next-images");
const withPlugins = require("next-compose-plugins");
const withBundleAnalyzer = require("@next/bundle-analyzer")({
  enabled: process.env.ANALYZE === "true",
});

module.exports = withPlugins([withBundleAnalyzer, withImages], {
  webpack(config, { webpack }) {
    return config;
  },
});

자 이제 완성된 헤더를 살펴보면 다음과 같은 코드가 나오게 됩니다.

기본적인 styled-components와 같은 컴포넌트 스타일링은 다루지 않습니다.

import React from "react";
import styled from "styled-components";
import LOGO from "../../public/img/logo.png";

export default function Header() {
  return (
    <HeaderContainer>
      <Inner>
        <LeftHeader>
          <div>
            <img src={LOGO} alt="logo" />
          </div>
          <ul>
            <li>PARTNER</li>
            <li>COMPANY</li>
            <li>EMPLOYMENT</li>
          </ul>
        </LeftHeader>
        <RightHeader>
          <i className="material-icons">menu</i>
          <span>MENU</span>
        </RightHeader>
      </Inner>
    </HeaderContainer>
  );
}

헤더의 네비게이션을 누르면 해당 페이지로 이동할 수 있는 기능을 넣어주어야 겠죠?
react-router-dom에서는 Link라는 기능을 이용해서 해당 기능을 구현해 주었는데, next에서도 마찬가지로 Link를 제공하고 있습니다.
사용방법또한 매우매우 간단합니다.

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">
          <a>Home</a>
        </Link>
      </li>
      <li>
        <Link href="/about">
          <a>About Us</a>
        </Link>
      </li>
      <li>
        <Link href="/blog/hello-world">
          <a>Blog Post</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home
  • next에서 Linkreact-router-dom과는 다르게 Link내부에 a태그를 하나 기술해 주어야 합니다.
  • 만약 아래와 같이 Link내부에 a태그로 감싸진 컴포넌트가 있는 경우가 있을 수 있습니다. (특히 styled-components)
<Link href={href} passHref>
   <RedLink>{name}</RedLink>
</Link>

이러한 경우에는 Link태그 내부에 passHref속성을 추가해 주어야만 SEO의 손상을 막을 수 있습니다!

  • Link의 기본동작 원리는 router.push()입니다. 만약 push대신 replace를 사용해주고 싶다면 아래와 같이 속성을 추가해 줄 수 있습니다.
<Link href="/about" replace>
  <a>About us</a>
</Link>
  • 또한 Link의 기본 액션은 a태그와 마찬가지로 페이지 상단으로의 스크롤입니다. 이를 이용해 #을 이용한 anchor를 만들어 줄 수도 있습니다. 단, 스크롤을 막아주고 싶다면 아래와 같이 scroll={false} 를 추가해 줄 수도 있습니다.
<Link href="/?counter=10" scroll={false}>
  <a>Disables scrolling to the top</a>
</Link>

0개의 댓글