saewoo
githubemail
2022-10-18

최신순으로 포스트 가져오기

방법은 많겠지만 어떻게 할까?

문제

인덱스 페이지 접근 시 fs 모듈의 readdirSync 함수를 사용하여 파일 이름을 읽어오고 그 파일 이름들을 인덱스 페이지에 그려주었습니다.

export const getFileNames = (path: string) => {
  const files = fs.readdirSync(path);
  const fileNames = files.map(file => file.split('.')[0]);
  return fileNames;
}
export const getPostNames = () => {
  return getFileNames('__posts');
}

포스팅을 '최신순'으로 노출시키고 싶은데

apple.md, cucumber.md파일이 있을때

__posts
┣ apple.md
┗ cucumber.md

banana.md라는 새로운 파일을 추가한다면 이름을 기준으로 정렬됐습니다.

__posts
┣ apple.md
┣ banana.md
┗ cucumber.md

고민

방법은 많겠지만 어떻게 할까?

md 파일을 gray-matter로 파싱하여 얻은 meta에 작성한 날짜를 기준으로 정렬할 수도 있지만,

그렇게 되면 '/'페이지와 '/posts/[id]' 두 곳에서 md를 파싱하게 되므로 맞지 않다고 생각했습니다.

또한 데이터 구조를 변경하여 인덱스 페이지에서 파싱해서 제목과 마크다운 HTML 모두를 'post/[id]'에 넘겨줄수도 있지만,

유저가 모든 포스팅을 읽을 것이 아닌데 모든 데이터를 처리해서 넘기는것은 비효율적이라고 생각했습니다.

따라서 현재의 데이터 구조를 유지하되 파일명으로만 데이터를 식별하기 위해서 이름 앞에 접두사로 숫자를 넣고 숫자를 기준으로 정렬하기로 했습니다.

해결

파일명에 접두사로 숫자를 적고

__posts
┣ 1_apple.md
┣ 2_cucumber.md
┗ 3_banana.md

getPostNames 호출시 숫자를 기준으로 내림차순 정렬을 하였습니다.

// index.tsx
const fileNames = getPostNames()
    .sort((name1, name2) => Number(name2.split('_')[0])- Number(name1.split('_')[0]));

이름을 그대로 사용할 경우 접두사(숫자_)가 보이므로 split 메서드로 제거해줬습니다.

return (
    <ul>
      {Posts.map((fileName: string, idx: number) => (
        <li key={ idx }>
          <Link href={`/posts/${ fileName }`}>
            { fileName.split('_')[1] }
          </Link>
        </li>
      ))}
    </ul>
  );