SSG 랜더스가 아니다
정적 사이트 생성기는 원시적인 데이터와 템플릿을 기반으로 정적 HTML 웹 사이트를 생성하는 도구 (출처)
유명한 site generator 들의 목록을 보면 도구가 굉장히 여러 개 있는 것을 알 수 있다.
눈에 띄는 녀석들 중에는 next.js 도 있고, 옛날부터 애용되어 왔던 gatsby, hugo, jekyll 과 같은 도구들도 전부 ssg에 속한다.
그 중에서 오늘 소개하고자 하는 도구는 docusaurus 이다.
페이스북에서 제작한, 오픈소스 프로젝트의 웹사이트를 쉽게 제작 / 배포 / 유지보수하기 위한 도구
소개 페이지를 잠시 살펴보니 다음과 같은 특징을 가지는 도구임을 알 수 있다.
대강 정적 사이트에 기본적으로 필요한 요소를 갖추면서도, 커스텀 가능한 여지를 리액트 컴포넌트로 구성하여 삽입할 수 있다는 점이 매우 매력적으로 느껴졌다.
아래에서 어떻게 사용할 수 있는지 살펴보자.
https://github.com/facebook/docusaurus
새 프로젝트 구성을 위해서는 github에 나와 있는 것처럼 npx cli를 통해 초기화 및 적용할 수 있었다.
npx create-docusaurus@latest my-website classic --typescript
그 후 동작을 시켜보면 아래와 같은 화면을 볼 수 있다.
프로젝트를 간단히 구성하고 공식 문서를 찬찬히 읽어보면서 지원하는 기능들을 알아보았다.
https://docusaurus.io/docs/api/docusaurus-config
docusaurus.config.ts
파일을 통해 문서 전반적인 설정을 할 수 있다.
사이드 바 (lnb 메뉴) 는 docusaurus 내부에서 별도 설정 파일을 통해 계층 구조가 정의된다.
*Ref
: 네비게이션 생성 없이 문서 페이지에 링크를 추가한다. 보다 자세한 사이드바 커스텀은 공식 문서를 참조 (https://docusaurus.io/docs/sidebar/items)
docusaurus에서는 algolia를 사용한 문서 내 검색을 잘 지원하고 있다.
문서 의 설명에 따르면 algolia를 사용한 검색 기능은 아래와 같은 특징을 가진다.
Algolia Docsearch
가 서비스 신청한 웹사이트를 일주일에 한번 주기로 크롤링하여 모든 컨텐츠에 대한 인덱스를 추가 (docusaurus 가 기본적으로 크롤링할 수 있는 sitemap.xml
파일을 생성한다)검색 기능에 인덱싱 전략이 굉장히 중요한 만큼, 직접 인덱싱 및 es를 구축할 필요 없이 클라우드 서비스를 연동하여 문서 내 검색을 운용할 수 있는 것은 장점으로 다가온다.
기본적인 mdx의 문법은 전부 지원하면서도, 부가적으로 docusaurus에서 제공하는 기본 컴포넌트들 또한 사용할 수 있다.
https://docusaurus.io/docs/markdown-features
예시를 들어보자면 몇 가지가 있다.
:::
를 추가하여 docusaurus 만의 정보 탭을 추가할 수도 있다.
:::info
admonition 테스트!!
:::
문서 내 위 코드를 삽입하면 이렇게 렌더링된다.
<Tabs>
<TabItem value="apple" label="Apple" default>
This is an apple 🍎
</TabItem>
<TabItem value="orange" label="Orange">
This is an orange 🍊
</TabItem>
<TabItem value="banana" label="Banana">
This is a banana 🍌
</TabItem>
</Tabs>
위와 같이 사전 정의된 탭 컴포넌트를 통해 간단하게 전환 가능한 탭을 구성할 수도 있다.
럼 스위즐이라는 칵테일이 있다. (swizzle stick이라고 불리는 막대기를 사용하여 만들어진다)
사실 docusaurus 자체에서 제공하는 mdx 컴포넌트들도 꽤 쓸만하지만 다양한 요구사항을 구현하기 위해서는 이들을 마개조해야 할 필요도 생긴다.
docusaurus에 붙어 확장 기능을 사용할 수 있게 하는 다양한 플러그인들을 사용한다면 더더욱 이를 체감하게 된다.
swizzle 기본적으로 cli를 사용하여 기존 컴포넌트를 eject 또는 wrap 할 수 있다.
npm run docusaurus swizzle
cli를 사용하여 swizzle 모드에 진입하게 되면 아래와 같은 대화창이 뜨는데, 커스텀을 원하는 테마를 선택한 뒤,
대상 언어를 선택한다. (docusaurus는 typescript 지원을 아주 잘하고 있다)
대상 컴포넌트를 선택한 후 eject / wrap을 선택하게 되면 아래와 같이 기존 컴포넌트를 eject / wrap 한 컴포넌트가 생성된 것을 확인할 수 있다. (예시에서는 Admonition
컴포넌트의 Info 아이콘을 선택하였다)
swizzle 을 통해 생성된 컴포넌트는 기본적으로 src/theme
디렉토리 하위에 생성된다. 이제 기존 docusaurus 컴포넌트에서 마음에 들지 않는 부분들을 직접 커스텀할 수 있게 되었다.
import React from 'react';
import type {Props} from '@theme/Admonition/Icon/Info';
export default function AdmonitionIconInfo(props: Props): JSX.Element {
return (
<a href="https://naver.com">
<svg viewBox="0 0 14 16" {...props}>
<path
fillRule="evenodd"
d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"
/>
</svg>
</a>
);
}
위 예시에서는 info 아이콘에 a 태그를 적용하여 아이콘 클릭 시 네이버 페이지로 이동하는 컴포넌트로 만들어보았다.
info 아이콘을 클릭했을 때 페이지가 잘 이동되는 것을 확인하였다.
지금까지는 docusaurus의 다양한 기능들을 알아보았다.
그런데 처음부터 mdx 파일을 작성하여 정적 api 문서를 만드는 것이 아니라 기존에 존재하던 oas3 포맷의 api 문서를 만들어야 한다면 어떨까?
바로 docusaurus-openapi-docs 플러그인을 사용하면 기존 swagger 등으로 제공하던 api 문서를 스타일리시하고도 커스텀 가능한 정적 문서를 생성할 수 있다.
우선 존재하던 docusaurus 프로젝트에 플러그인을 설정해야 한다.
나는 npm
를 사용하고 있으므로, 다음을 실행한다.
npm install docusaurus-plugin-openapi-docs docusaurus-theme-openapi-docs
그 후 예시로 사용할 oas3 문서 데이터를 다운로드 받아, 프로젝트 리소스 파일에 넣어준다.
예시를 들기 위해 swagger 샘플 yaml 데이터 를 다운로드 받아 /static/openapi
디렉토리 하위에 넣어주었다.
플러그인과 문서 데이터가 정상적으로 세팅 되었다면, docusaurus.config.ts
파일을 통해 플러그인 설정을 해준다.
별다른 것은 없고, 예시 에 있는 설정을 기존 config에 녹여낸다.
다음과 같은 형태가 될 것이다.
presets: [
[
"classic",
{
docs: {
sidebarPath: "./sidebars.ts",
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/",
},
blog: {
showReadingTime: true,
feedOptions: {
type: ["rss", "atom"],
xslt: true,
},
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/",
// Useful options to enforce blogging best practices
onInlineTags: "warn",
onInlineAuthors: "warn",
onUntruncatedBlogPosts: "warn",
},
theme: {
customCss: "./src/css/custom.css",
},
} satisfies Preset.Options,
],
],
plugins: [
[
"docusaurus-plugin-openapi-docs",
{
id: "api", // plugin id
docsPluginId: "classic", // configured for preset-classic
config: {
petstore: {
specPath: "static/openapi/example.yaml",
outputDir: "docs/example",
sidebarOptions: {
groupPathsBy: "tag",
},
} satisfies OpenApiPlugin.Options,
},
},
],
],
themes: ["docusaurus-theme-openapi-docs"],
// ...
]
이제 oas3 문서 데이터를 기반으로 자동으로 docusaurus mdx 컴포넌트를 생성할 차례이다.
npm run docusaurus gen-api-docs all
api
로 설정하였다.gen-api-docs
의 인자로 id를 설정할 수도 있고, all
로 설정할 경우 전체 문서를 생성한다.clean-api-docs
는 id가 지정된 경우 해당 문서를, all
을 입력하는 경우 전체 문서를 제거한다.gen-api-docs:version
을 통해 oas3 문서 데이터 내부 버전 별로 문서의 버전 관리를 할 수 있다.아래와 같이 문서가 생성되었다면 성공이다.
생성된 문서는 tutorial
탭에서 확인할 수 있는데, 기본 sidebar 설정이 tutorial 로 매핑되어 있기 때문이다. (추후 위치 변경도 자유롭다)
완료되었다! 이렇게 자동 생성된 문서 내에는 지금까지 알아봤던 것처럼 직접 커스텀한 리액트 컴포넌트를 삽입시키거나 docusaurus에서 기본 지원하는 컴포넌트들을 사용하여 openapi 문서를 직접 작성할 수 있다.
간단히 적용을 해보면 docusuarus 생태계에 대해 느낀 장단점을 요약하자면,
별점 ⭐⭐⭐⭐ (4.0 / 5) : 마크다운 기반의 커스텀 가능한 문서 페이지를 간편한 방식으로 만들 수 있는 라이브러리. 다양한 플러그인과 함께라면 쓰임새가 무궁무진해보인다.