Skip to main content
버전: 3.6.3

MDX와 리액트

도큐사우루스는 MDX를 기본 지원하므로 마크다운 파일 안에 JSX를 작성하고 리액트 컴포넌트로 렌더링할 수 있습니다.

MDX로 어떤 멋진 작업을 할 수 있는지 MDX 문서를 살펴보세요.

MDX 디버깅

MDX 형식은 매우 엄격하여 컴파일 오류가 발생할 수 있습니다.

**MDX 플레이그라운드**를 사용해 디버깅하고 구문이 유효한지 확인하세요.

정보

가장 널리 사용되는 포매터인 Prettier는 기존 MDX v1만 지원합니다. 의도하지 않은 서식 결과가 나오면 Prettier가 MDX v3를 제대로 지원할 때까지 문제가 있는 부분 앞에 {/* prettier-ignore */}를 추가하거나 .prettierignore에 *.mdx를 추가할 수 있습니다. MDX의 주요 개발자 중 한 명은 remark-cli와 remark-mdx를 함께 사용할 것을 권장합니다.

컴포넌트 내보내기​

MDX 파일 안에서 사용자 정의 컴포넌트를 정의하려면 내보내야 합니다. export로 시작하는 문단만 일반 텍스트 대신 컴포넌트로 파싱됩니다.

export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);

<Highlight color="#25c2a0">도큐사우루스 초록색</Highlight>과 <Highlight color="#1877F2">페이스북 파란색</Highlight>은 제가 좋아하는 색입니다.

_JSX_와 함께 **마크다운**도 작성할 수 있습니다!

리액트 컴포넌트의 마크업과 마크다운 구문이 모두 렌더링되는 모습을 확인하세요:

http://localhost:3000
도큐사우루스 초록색 그리고 페이스북 파란색은 제가 좋아하는 색입니다.

_JSX_와 함께 마크다운도 작성할 수 있습니다!

MDX는 JSX입니다

모든 문서 파일은 MDX로 파싱되므로 HTML처럼 보이는 것도 실제로는 JSX입니다. 따라서 컴포넌트에 인라인 스타일을 지정하려면 JSX 방식에 따라 스타일 객체를 제공하세요.

/* 다음 코드 대신: */
<span style="background-color: red">Foo</span>
/* 이 코드를 사용하세요: */
<span style={{backgroundColor: 'red'}}>Foo</span>

컴포넌트 가져오기​

다른 파일에서 정의한 자체 컴포넌트나 npm으로 설치한 외부 컴포넌트를 가져올 수도 있습니다.

<!-- 도큐사우루스 테마 컴포넌트 -->
import TOCInline from '@theme/TOCInline';
<!-- 외부 컴포넌트 -->
import Button from '@mui/material/Button';
<!-- 사용자 정의 컴포넌트 -->
import BrowserWindow from '@site/src/components/BrowserWindow';
팁

@site 별칭은 웹사이트 디렉터리, 일반적으로 docusaurus.config.js 파일이 있는 곳을 가리킵니다. 상대 경로('../../src/components/BrowserWindow') 대신 별칭을 사용하면 파일을 이동하거나 문서 버전을 관리하고 번역할 때 가져오기 경로를 수정할 필요가 없습니다.

단순한 경우에는 마크다운 안에서 컴포넌트를 선언하는 것이 매우 편리하지만, 편집기 지원이 제한적이고 파싱 오류의 위험이 있으며 재사용성이 낮아 유지보수가 어려워집니다. 컴포넌트에 복잡한 JS 로직이 포함된다면 별도의 .js 파일을 사용하세요:

src/components/Highlight.js
import React from 'react';

export default function Highlight({children, color}) {
return (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);
}
markdown-file.mdx
import Highlight from '@site/src/components/Highlight';

<Highlight color="#25c2a0">도큐사우루스 초록색</Highlight>
팁

많은 파일에서 같은 컴포넌트를 사용한다면 모든 파일에서 가져올 필요 없이 전역 스코프에 추가하는 것을 고려해 보세요. 아래 내용 참고

MDX 컴포넌트 스코프​

컴포넌트 가져오기와 컴포넌트 내보내기 외에 MDX에서 컴포넌트를 사용하는 세 번째 방법은 전역 스코프에 등록하는 것입니다. 이렇게 하면 가져오기 구문 없이도 모든 MDX 파일에서 자동으로 사용할 수 있습니다.

예를 들어 다음과 같은 MDX 파일이 있다고 가정해 보겠습니다:

- 목록
- 항목!

그리고 <Highlight>사용자 정의 마크업</Highlight>도...

이 파일은 ul, li, p, Highlight 요소가 포함된 리액트 컴포넌트로 컴파일됩니다. Highlight는 기본 HTML 요소가 아니므로 이에 해당하는 리액트 컴포넌트를 직접 구현해야 합니다.

도큐사우루스에서 MDX 컴포넌트 스코프는 @theme/MDXComponents 파일로 제공됩니다. @theme/ 별칭에서 내보내는 대부분의 항목과 달리, 이 파일은 그 자체로 리액트 컴포넌트가 아닙니다. Highlight 같은 태그 이름을 해당 리액트 컴포넌트 구현에 연결하는 레코드입니다.

이 컴포넌트를 스위즐링하면 구현된 모든 태그를 확인할 수 있습니다. @theme/MDXComponents/Code(마크다운 코드 블록을 렌더링하는 데 사용)처럼 해당 하위 컴포넌트를 스위즐링하여 구현을 추가로 수정할 수도 있습니다.

위의 \<Highlight> 태그처럼 태그 이름을 추가로 등록하려면 @theme/MDXComponents를 래핑하는 것을 고려하세요. 그러면 기존 매핑을 모두 유지보수할 필요가 없습니다. 스위즐링 CLI는 아직 컴포넌트가 아닌 파일의 래핑을 지원하지 않으므로 래퍼를 직접 만들어야 합니다:

src/theme/MDXComponents.js
import React from 'react';
// 원본 매퍼 가져오기
import MDXComponents from '@theme-original/MDXComponents';
import Highlight from '@site/src/components/Highlight';

export default {
// 기본 매핑 재사용
...MDXComponents,
// "<Highlight>" 태그를 Highlight 컴포넌트에 매핑
// `Highlight`는 MDX의 `<Highlight>`에 전달된 모든 props를 받습니다
Highlight,
};

이제 가져오기 구문 없이도 모든 페이지에서 \<Highlight>를 자유롭게 사용할 수 있습니다:

어디서나 <Highlight color="#25c2a0">도큐사우루스 초록색</Highlight>을 편리하게 사용할 수 있습니다!
http://localhost:3000

어디서나 도큐사우루스 초록색을 편리하게 사용할 수 있습니다!

경고

Highlight처럼 대문자로 시작하는 태그 이름을 의도적으로 사용합니다.

From MDX v3+ onward (Docusaurus v3+), lower-case tag names are always rendered as native html elements, and will not use any component mapping you provide.

경고

이 기능은 MDXProvider를 기반으로 합니다. 리액트 페이지에서 마크다운을 가져오는 경우 MDXContent 테마 컴포넌트를 통해 이 프로바이더를 직접 제공해야 합니다.

src/pages/index.js
import React from 'react';
import FeatureDisplay from './_featureDisplay.mdx';
import MDXContent from '@theme/MDXContent';

export default function LandingPage() {
return (
<div>
<MDXContent>
<FeatureDisplay />
</MDXContent>
</div>
);
}

가져온 MDX를 MDXContent로 감싸지 않으면 전역 스코프를 사용할 수 없습니다.

마크다운과 JSX 상호 운용성​

Docusaurus v3 is using MDX v3.

MDX 구문은 대부분 CommonMark와 호환됩니다. 하지만 .mdx 파일에서 JSX를 사용할 수 있고 실제 리액트 컴포넌트로 컴파일되므로 훨씬 엄격합니다(플레이그라운드 참고).

일부 유효한 CommonMark 기능은 MDX에서 동작하지 않습니다(자세히 보기). 대표적인 예는 다음과 같습니다:

  • 들여쓴 코드 블록: 대신 백틱 3개를 사용하세요
  • 자동 링크(\<http://localhost:3000>): 대신 일반 링크 구문([http://localhost:3000](http://localhost:3000))을 사용하세요
  • HTML 구문(\<p style="color: red;">): 대신 JSX(\<p style={{color: 'red'}}> )를 사용하세요
  • 이스케이프하지 않은 {와 \<: 대신 ``로 이스케이프하세요({와 \<)
실험적인 CommonMark 지원

Docusaurus v3 makes it possible to opt-in for a less strict, standard CommonMark support with the following options:

  • mdx.format: md 프런트 매터
  • .md 파일 확장자와 siteConfig.markdown.format: "detect" 설정의 조합

이 기능은 실험적이며 현재 몇 가지 제한사항이 있습니다.

코드 조각 가져오기​

You can not only import a file containing a component definition, but also import any code file as raw text, and then insert it in a code block, thanks to Webpack raw-loader. In order to use raw-loader, you first need to install it in your project:

npm install --save raw-loader

Now you can import code snippets from another file as it is:

myMarkdownFile.mdx
import CodeBlock from '@theme/CodeBlock';
import MyComponentSource from '!!raw-loader!./myComponent';

<CodeBlock language="jsx">{MyComponentSource}</CodeBlock>
http://localhost:3000
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import {useState} from 'react';

export default function MyComponent() {
const [bool, setBool] = useState(false);
return (
<div>
<p>MyComponent rendered !</p>
<p>bool={bool ? 'true' : 'false'}</p>
<p>
<button onClick={() => setBool((b) => !b)}>toggle bool</button>
</p>
</div>
);
}

\<CodeBlock> 컴포넌트에 대한 자세한 내용은 JSX에서 코드 블록 사용하기를 참고하세요.

참고

마크다운의 백틱 3개 ``` 대신 \<CodeBlock>을 사용해야 합니다. 백틱 안의 내용은 그대로 출력되지만, 여기서는 가져온 텍스트를 보간해야 하기 때문입니다.

경고

이 기능은 실험적이며 향후 호환성을 깨뜨리는 API 변경이 있을 수 있습니다.

마크다운 가져오기​

마크다운 파일을 컴포넌트로 사용하고 다른 마크다운 파일이나 리액트 페이지에서 가져올 수 있습니다. 각 MDX 파일은 페이지 콘텐츠를 리액트 컴포넌트로 기본 내보내기합니다. import 구문에서 이 컴포넌트를 원하는 이름으로 기본 가져오기할 수 있지만, 리액트 명명 규칙에 따라 대문자로 시작해야 합니다.

관례적으로 파일 이름에 _ 접두사를 사용하면 문서 페이지를 생성하지 않으며, 다른 파일에서 가져와 사용하는 **"부분 파일"**임을 나타냅니다.

_markdown-partial-example.mdx
<span>안녕하세요, {props.name}님</span>

이 텍스트는 `_markdown-partial-example.mdx`의 콘텐츠입니다.
someOtherDoc.mdx
import PartialExample from './_markdown-partial-example.mdx';

<PartialExample name="Sebastien" />
http://localhost:3000
Hello Sebastien

This is text some content from _markdown-partial-example.md.

이렇게 하면 여러 페이지에서 콘텐츠를 재사용하고 자료의 중복을 피할 수 있습니다.

사용 가능한 내보내기 항목​

MDX 페이지 안에서는 다음 변수를 전역으로 사용할 수 있습니다:

  • frontMatter: 문자열 키와 값으로 이루어진 레코드 형태의 프런트 매터;
  • toc: 제목 트리 형태의 목차입니다. 구체적인 사용 사례는 인라인 목차도 참고하세요.
  • contentTitle: 마크다운 텍스트에서 첫 번째 h1 제목인 마크다운 제목입니다. 해당 제목이 없으면(예: 프런트 매터에서 제목 지정) undefined입니다.
import TOCInline from '@theme/TOCInline';
import CodeBlock from '@theme/CodeBlock';

이 페이지의 목차를 직렬화한 결과:

<CodeBlock className="language-json">{JSON.stringify(toc, null, 2)}</CodeBlock>

이 페이지의 프런트 매터:

<ul>
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
</ul>

<p>이 페이지의 제목: <b>{contentTitle}</b></p>
http://localhost:3000

이 페이지의 목차를 직렬화한 결과:

[
{
"value": "컴포넌트 내보내기",
"id": "exporting-components",
"level": 3
},
{
"value": "컴포넌트 가져오기",
"id": "importing-components",
"level": 3
},
{
"value": "MDX 컴포넌트 스코프",
"id": "mdx-component-scope",
"level": 3
},
{
"value": "마크다운과 JSX 상호 운용성",
"id": "markdown-and-jsx-interoperability",
"level": 3
},
{
"value": "코드 조각 가져오기",
"id": "importing-code-snippets",
"level": 2
},
{
"value": "마크다운 가져오기",
"id": "importing-markdown",
"level": 2
},
{
"value": "사용 가능한 내보내기 항목",
"id": "available-exports",
"level": 2
}
]

이 페이지의 프런트 매터:

  • id: react
  • description: MDX를 사용해 도큐사우루스 마크다운 문서 내에서 리액트의 강력한 기능을 활용할 수 있습니다.
  • slug: /markdown-features/react

이 페이지의 제목: MDX와 리액트