Post들이 저장된 FileSystem 파싱하기
개발 블로그 개발 여정
reactnextjsmdx
Sat Jun 01 2024
이 글은 개발 블로그 개발 여정의 게시글이예요
해당 포스트는 NextJS를 이용하여 개발 블로그를 만들며 작성한 포스트입니다.
기술 블로그의 전체 코드는 🪢 yonglog github 에서 확인 하실 수 있습니다.
- 1 . 개발블로그 제작을 시작하며
- 2 . CI/CD 파이프라인 구성하기
- 3 . tailwind 환경 설정 및 디자인 레퍼런스 찾기
- 4 . / 경로 레이아웃 , 페이지 디자인 생성하기
- 5 . [BUG] Build 시 발생하는 typeError 해결하기
- 6 . MDX를 사용하기 위한 라이브러리들 설치 및 환경 설정
- 7 . Post들이 저장된 FileSystem 파싱하기
- 8 . PageNavigation UI 만들기
- 9 . tag , series Identifier 만들기
- 10 . / 경로 UI 디자인 하기
- 11 . 서버 컴포넌트에 Dynamic Routing 추가하기
- 12 . Post/page.tsx 생성하기
- 13 . 마크다운 파일 코드블록 꾸미기
- 14 . [BUG] Vercel 에 환경 변수 추가하기
- 15 . Loading Suspense 구현하기
- 16 . generateStaticParams 이용해 SSR 에서 SSG로 넘어가자
- 17 . SSG를 이용한 블로그에서 테마 변경하기
- 18 . 인터렉티브한 사이드바 만들기
- 19 . 기술블로그에 giscus를 이용하여 댓글 기능을 추가하기
- 20 . 기술 블로그의 SEO를 최적화 하기 위한 방법 Part1
- 21 . 기술 블로그의 SEO를 최적화 하기 위한 방법 Part2
- 22 . 바닐라 자바스크립트로 깃허브 OAuth 를 구현해보자
- 23 . 라이브러리 없이 깃허브 API를 이용해 댓글창을 구현해보자
- 24 . 리팩토링 : Promise 패턴을 이용하여 비동기 처리중인 전역 객체에 접근하기
- 25 . NextJS로 만든 기술블로그에서 검색 기능 구현하기
이전 챕터에서 posts
라는 폴더 내에 시리즈 별 포스트들을 정의해주었다. (아직은 하나밖에 존재하지 않지만)
이제 posts
폴더 내에 정의된 파일 구조를 파싱하여 자료구조를 만들도록 하자
자료구조를 만들어 posts
들의 게시글들을 이용해 게시글 리스트나 라우팅 경로에 따라 게시글을 렌더링 하기 위함이다.
@/posts 폴더 파싱하여 자료구조 만들기
NextJS
의 가장 큰 장점이라 한다면 브라우저 상의 로직 뿐 아니라, 서버 단의 로직 또한 다룰 수 있기 때문에 렌더링 과정에서 나의 로컬 파일을 접근하고 사용 할 수 있다는 점이다.
만약 NextJS
와 같은 풀스택 프레임워크가 아닌 React
만을 이용해서 구현했다고 생각한다면 글들만을 저장하는 데이터베이스를 생성하고
데이터베이스에 API
요청을 보내 정보를 가져와야 했겠지만 NextJS
에선 단순히 로컬 파일에 접근하여 직접 사용하는 것이 가능하다.
타입 선언하기
post
들을 가져올 때 사용할 타입들을 @types/post.d.ts
에 정의해준다.
컴파일 시에만 사용할 타입들이기 때문에 .d.ts
로 정의해주었다.
타입 선언들은 사용하는 예시를 보며 파악하도록 하고 , Dierectory , MDXSource
타입들을 살펴보자
아아
기본 Source
타입에서 __
가 붙은 nominal type
을 확장해준 모습을 볼 수 있다.
normianl type system
In computer science, a type system is nominal (also called nominative or name-based) if compatibility and equivalence of data types is determined by explicit declarations and/or the name of the types. Nominal systems are used to determine if types are equivalent, as well as if a type is a subtype of another. Nominal type systems contrast with structural systems, where comparisons are based on the structure of the types in question and do not require explicit declarations.
🪢 🪢 위키피디아 - Toggle the table of contents Nominal type system
이렇게 nominal type
을 이용해 고유한 타입을 생성해줄 수 있다.
예를 들어 Direcotry
는 기본적인 타이핑 구조가 Source
와 같지만 Directory
타입으로 선언된 객체는 {__directory : true}
인 nominal type
으로 확장되었기 때문에
Source
와 다른 Direcotry
라는 고유한 타입을 가질 수 있다.
일반적인 타입 선언과 다르게
nominal type
은 실제 자료 구조에서__directory : true
라는 타입을 가질 필요가 없다. 그저nominal type
은 고유한 타입을 선언하기 위한 구별자에 불과하다. 유형 정의에만 사용 될 뿐 런타임 데이터엔 필요하지 않다.
이를 통해 타입 안정성을 보장하고 오류를 방지 할 수 있다.
app/lib/post.tsx
최상단 경로 /
에서 로컬 폴더에 존재하는 Post
들을 가져오는 메소드를 정의해주자
사용할 라이브러리
써드파티 라이브러리 하나를 설치해주자
해당 라이브러리는 MDX
파일을 파싱했을 때 ---
블록으로 나눴던 meta
데이터와 본문 데이터를 구분하여 파싱해준다.
---
// -- 블록 내부는 meta 로 파싱된다.
title: 'MDX를 사용하기 위한 라이브러리들 설치 및 환경 설정'
series: '개발블로그 제작기'
description: '필요한 라이브러리들을 설치하고 환경 설정을 해보자'
date: '2024-05-31'
tag: ['react', 'nextjs', 'mdx']
---
// -- 이하의 내용은 data 로 파싱된다.
# MDX 를 사용하기 위한 라이브러리 설치하기
타입 가드 설정하기
두 메소드는 파일 경로에 대해 해당 파일이 Directory
인지, 혹은 MDX
파일인지를 확인하는 타입가드이다.
해당 타입 가드를 통해 위에서 선언한 nominal type
인 Directory , MDXSource
타입으로 선언해줄 수 있다.
fs.lstatSync
: 파일의 정보를 담은fs.Stats
객체를 동기적으로 확인한다.path.basename
: 해당 경로의 마지막 부분을 확인한다.path.extname
: 해당 경로 마지막 부분의 확장자를 확인한다.
필요한 정보들 가져오기
getAllPath
:source
에 존재하는 모든 파일들의 경로를 반환한다.getSeriesName
,getPostId
: 이 두 메소드는meta
데이터를 생성하기 위해 생성한 메소드이다.
다음과 같이 mdx
파일의 경로인 MDXSource
를 만났을 때 ../..
에 존재하는 폴더 명을 이용해 시리즈 이름을 반환하고 , ..
경로에 존재하는 폴더 명을 이용해 해당 포스트의 id
를 반환한다.
매번 MDX
파일에 메타 데이터들을 적어주기 귀찮았기 때문에 해당 메소드를 생성해주었다.
posts 폴더 파싱하여 자료구조 만들기
parsePosts
라는 메소드를 정의해 source
내부에 존재하는 모든 mdx
파일을 파싱해오는 메소드를 생성해주었다.
내부에서 parseRecursively
라는 메소드를 재귀적으로 호출하여 source
의 최하단 하위경로까지 탐색하며 .mdx
파일을 만날 때 까지 탐색한다.
이후 .mdx
인 파일을 만나면 gray-matter
를 이용해 해당 .mdx
파일의 메타 데이터와 본문 데이터를 파싱 한 후 여러 메타 정보를 혼합해 Posts
배열에 추가한다.
이후 Posts
를 반환하면 /posts
폴더에 존재하는 모든 .mdx
파일들을 메타정보들과 함께 파싱해오는 것이 가능하다.
마지막으로 parsePosts
메소드를 posts
를 인수로 건내 모든 mdx
파일들을 파싱 해온후 해당 파일들을 정렬한 후 반환하는 getAllPosts
메소드를 정의해주었다.
정렬 기준은 최신순으로 정렬하는데, 만약 날짜가 같다면 postId
를 통해 정렬하도록 하였다.
getAllPosts 가 잘 작동하는지 확인해보자
/
경로의 페이지에서 getAllPosts
를 호출한 후 반환된 allPosts
를 이용해 게시글 리스트를 렌더링해줬다.
우선 꾸미는 작업은 나중에 하기로 했기 때문에 기본적인 스타일링만 해주고 살펴보았다.
잘 작동하고 잘 가져와진다. :)