[Docusaurus doc/blog] Swizzling(스위즐링)으로 원하는 대로 도큐사우르스 커스터마이징하기(꾸미기)



1. 도큐사우르스의 스위즐링(Swizzling)이란?

도큐사우르스에서 제공해주는 기본적인 컴포넌트나 테마 이외에, 사용자가 원하는 컴포넌트에 값을 추가로 넣거나 컴포넌트를 수정하고 싶은 경우가 있을 것입니다. 사이드바에 원하는 것을 넣거나, 페이지네이션을 구성하거나, 다양한 종류의 커스터미이징을 하고 싶은 경우가 많을 것 같은데요.

이것을 하기 위해서는 도큐사우루스의 핵심 개념인 스위즐링(Swizzling)에 대해 다룰 겁니다. 이를 통하여 유저가 원하는 커스터마이징을 할 수 있습니다.스위즐링(Swizzling)은 테마 컴포넌트를 유저가 작성하여 변경할 수 있으며, 아래의 두 가지 패턴으로 제공됩니다.

  • Ejecting(추출하기)
    • 원본 컴포넌트의 복사본을 만들어 원하는 형태로 사용자 지정할 수 있습니다.
    • 기존 컴포넌트를 건드려서 유저가 원하는 대로 사용할 수 있습니다.
  • Wrapping(감싸기)
    • 원본 컴포넌트를 감싼 형태로 기능을 향상시킬 수 있습니다.
    • 기존 컴포넌트는 건드리지 않고 그 위에 유저가 원하는대로 수정할 수 있습니다.

2. 사용 방법

2.1. swizzle 가능한 리스트 확인하기

$ yarn swizzle --list

위의 명령어를 통해서 스위즐링(Swizzling) 가능한 컴포넌트가 어떤 것이 있는지 확인할 수 있습니다. 위의 명령어를 수행하면 아래와 같은 데이터가 나옵니다.

yarn run v1.22.17
$ docusaurus swizzle --list

   ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
   │                                                                                                                                                              │
   │                                                                Update available 2.1.0 → 2.2.0                                                                │
   │                                                                                                                                                              │
   │                                       To upgrade Docusaurus packages with the latest version, run the following command:                                     │
   │     `yarn upgrade @docusaurus/core@latest @docusaurus/plugin-content-blog@latest @docusaurus/preset-classic@latest @docusaurus/module-type-aliases@latest`   │
   │                                                                                                                                                              │
   ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

[INFO] All theme components available to swizzle:

Components available for swizzle in @docusaurus/theme-classic:
┌──────────────────────────────────────────┬───────────┬───────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Component name                           │ Wrap      │ Eject     │ Description                                                                                                                                 │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ CodeBlock                                │ Safe      │ Safe      │ The component used to render multi-line code blocks, generally used in Markdown files.                                                      │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ColorModeToggle                          │ Safe      │ Safe      │ The color mode toggle to switch between light and dark mode.                                                                                │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ DocCardList                              │ Safe      │ Safe      │ The component responsible for rendering a list of sidebar items cards.                                                                      │
│                                          │           │           │ Notable used on the category generated-index pages.                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer                                   │ Safe      │ Safe      │ The footer component of you site's layout                                                                                                   │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/Copyright                         │ Safe      │ Safe      │ The footer copyright                                                                                                                        │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/Layout                            │ Safe      │ Safe      │ The footer main layout component                                                                                                            │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/LinkItem                          │ Safe      │ Safe      │ The footer link item component                                                                                                              │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/Links                             │ Safe      │ Safe      │ The footer component rendering the footer links                                                                                             │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/Links/MultiColumn                 │ Safe      │ Safe      │ The footer component rendering the footer links with a multi-column layout                                                                  │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/Links/Simple                      │ Safe      │ Safe      │ The footer component rendering the footer links with a simple layout (single row)                                                           │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Footer/Logo                              │ Safe      │ Safe      │ The footer logo                                                                                                                             │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Icon/Arrow                               │ Safe      │ Safe      │ The arrow icon component                                                                                                                    │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Icon/DarkMode                            │ Safe      │ Safe      │ The dark mode icon component.                                                                                                               │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Icon/Edit                                │ Safe      │ Safe      │ The edit icon component                                                                                                                     │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Icon/LightMode                           │ Safe      │ Safe      │ The light mode icon component.                                                                                                              │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Icon/Menu                                │ Safe      │ Safe      │ The menu icon component                                                                                                                     │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/A                          │ Safe      │ Safe      │ The component used to render <a> tags and Markdown links in MDX                                                                             │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/Code                       │ Safe      │ Safe      │ The component used to render <code> tags and Markdown code blocks in MDX                                                                    │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/Details                    │ Safe      │ Safe      │ The component used to render <details> tags in MDX                                                                                          │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/Heading                    │ Safe      │ Safe      │ The component used to render heading tags (<h1>, <h2>...) and Markdown headings in MDX                                                      │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/Img                        │ Safe      │ Safe      │ The component used to render <img> tags and Markdown images in MDX                                                                          │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/Pre                        │ Safe      │ Safe      │ The component used to render <pre> tags in MDX                                                                                              │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents/Ul                         │ Safe      │ Safe      │ The component used to render <ul> tags and Markdown unordered lists in MDX                                                                  │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXContent                               │ Safe      │ Safe      │ A component wrapping all MDX content and providing the MDXComponents to the MDX context                                                     │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ NotFound                                 │ Safe      │ Safe      │ The global 404 page of your site, meant to be ejected and customized                                                                        │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ SearchBar                                │ Safe      │ Safe      │ The search bar component of your site, appearing in the navbar.                                                                             │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ DocSidebar                               │ Safe      │ Unsafe    │ The sidebar component on docs pages                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MDXComponents                            │ Forbidden │ Safe      │ The MDX components to use for rendering MDX files. Meant to be ejected.                                                                     │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ NavbarItem/ComponentTypes                │ Forbidden │ Safe      │ The Navbar item components mapping. Can be ejected to add custom navbar item types. See https://github.com/facebook/docusaurus/issues/7227. │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ prism-include-languages                  │ Forbidden │ Safe      │ The Prism languages to include for code block syntax highlighting. Meant to be ejected.                                                     │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Admonition                               │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ AnnouncementBar                          │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ AnnouncementBar/CloseButton              │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ AnnouncementBar/Content                  │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ BackToTopButton                          │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ BlogArchivePage                          │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ BlogLayout                               │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ BlogListPage                             │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ BlogListPaginator                        │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ BlogPostItem                             │ Unsafe    │ Unsafe    │ N/A                                                                                                                                         │
├──────────────────────────────────────────┼───────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
... 
  • 리스트에서 현재 Swizzling 가능한 컴포넌트들을 확인할 수 있습니다.
  • Safe, Unsafe, Forbidden은 아래와 같은 의미를 가지고 있습니다.
    • Safe : 컴포넌트가 스위즐 시 안전하고 공개된 API가 안정적인 것으로 간주되며 메이저 버전 테마 내에서 주요한 변경 사항이 발생하지 않습니다.
    • Unsafe : 컴폰넌트가 테마 내부 구현 사항이기 때문에 스위즐 시 안전하지 않으며 마이너 버전 테마 내에서 주요 변경 사항이 발생할 수 있습니다.
    • Forbidden : swizzle CLI은 해당 컴포넌트를 스위즐할 수 없게 설계되었고 컴포넌트 스위즐을 할 수 없습니다.

2.2. Swizzle 동작하기 - Ejecting(추출하기)

$ yarn swizzle [theme name] [component name] -- --eject

$ yarn swizzle @docusaurus/theme-classic Footer -- --eject

위의 명령어를 통하여 원하는 component 를 Ejecting 하게 되면 기존 소스코드까지 나오게 되면서, 기존 값도 변경할 수 있습니다.

import React from 'react';

export default function Footer(props) {
  return (
    <footer>
      <h1>This is my custom site footer</h1>
      <p>And it is very different from the original</p>
    </footer>
  );
}

2.3. Swizzle 동작하기 - Wrapping(감싸기)

$ yarn swizzle [theme name] [component name] -- --wrap

$ yarn swizzle @docusaurus/theme-classic Footer -- --wrap

위의 명령어를 통하여 원하는 component 를 Wrapping 하게 되면 기존 소스코드는 수정하지 않은 상태에서, 원하는 값을 넣어줄 수 있습니다.

import React from 'react';
import Footer from '@theme-original/Footer';

export default function FooterWrapper(props) {
  return (
    <>
      <section>
        <h2>Extra section</h2>
        <p>This is an extra section that appears above the original footer</p>
      </section>
      <Footer {...props} />
    </>
  );
}

reference

  • https://docusaurus.io/ko/docs/swizzling