MDX ์ฝ๋ ๋ธ๋ก ์คํ์ผ๋ง: rehype-pretty-code์ remark-gfm ๊ฐ์ด๋
Next.js์์ MDX๋ฅผ ์ฌ์ฉํ ๋, ๊ธฐ๋ณธ ์ฝ๋ ๋ธ๋ก์ ๋ฐ๋ฐํ ํ ์คํธ๋ก ํ์๋ฉ๋๋ค. ์ด๋ฅผ VS Code์ฒ๋ผ ์์ ํ์ด๋ผ์ดํ ๊ณผ ๊ธฐ๋ฅ์ ๊ฐ์ถ ์ฝ๋ ๋ธ๋ก์ผ๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ์ ์์๋ด ๋๋ค.
1. ํ์ ํ๋ฌ๊ทธ์ธ ์ค์น
์ฝ๋ ํ์ด๋ผ์ดํ
์ ์ํ rehype-pretty-code์ GitHub ์คํ์ผ ๋ฌธ๋ฒ(ํ, ์ฒดํฌ๋ฆฌ์คํธ ๋ฑ)์ ์ง์ํ๋ remark-gfm์ ์ค์นํฉ๋๋ค.
npm install next-mdx-remote rehype-pretty-code remark-gfm shiki2. Next.js ์ค์ (next.config.mjs)
ํ๋ฌ๊ทธ์ธ์ ๋ฑ๋กํ๊ณ ํ์ด๋ผ์ดํ ํ ๋ง๋ฅผ ์ค์ ํฉ๋๋ค.
import remarkGfm from 'remark-gfm';
import rehypePrettyCode from 'rehype-pretty-code';
/** @type {import('rehype-pretty-code').Options} */
const options = {
theme: 'one-dark-pro', // ๋ค์ํ ํ
๋ง ์ ํ ๊ฐ๋ฅ (github-dark, dracula ๋ฑ)
keepBackground: true,
};
const nextConfig = {
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
// MDX ์ค์
experimental: {
mdxRs: true,
},
};
// MDX ๊ตฌ์ฑ ํจ์ (๋ฒ์ ์ ๋ฐ๋ผ ์ค์ ๋ฐฉ์์ด ๋ค๋ฅผ ์ ์์)
export default withMDX({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm], // ํ, ๋ฆฌ์คํธ ๋ฑ ํ์ฅ ๋ฌธ๋ฒ ์ง์
rehypePlugins: [[rehypePrettyCode, options]], // ์ฝ๋ ํ์ด๋ผ์ดํ
},
})(nextConfig);3. ์ฃผ์ ๊ธฐ๋ฅ ํ์ฉ๋ฒ
โ ๋ผ์ธ ํ์ด๋ผ์ดํ
์ฝ๋ ๋ธ๋ก ์๋จ์ {} ๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ค์ ๊ฐ์กฐํ ์ ์์ต๋๋ค.
// 1๋ฒ ์ค๊ณผ 3, 4๋ฒ ์ค์ด ๊ฐ์กฐ๋ฉ๋๋ค.
const a = 1;
const b = 2;
const c = 3;โก ํ์ผ ์ด๋ฆ ํ์
title="ํ์ผ๋ช
" ์์ฑ์ ์ถ๊ฐํ์ฌ ์ฝ๋ ๋ธ๋ก ์๋จ์ ํ์ผ๋ช
์ ํ์ํ ์ ์์ต๋๋ค.
export const add = (a: number, b: number) => a + b;4. CSS ์คํ์ผ๋ง (Tailwind CSS ๊ธฐ์ค)
rehype-pretty-code๊ฐ ์์ฑํ๋ ๋ฐ์ดํฐ ์์ฑ์ ์ด์ฉํด ์คํ์ผ์ ์
ํ๋๋ค.
/* ๊ธ๋ก๋ฒ CSS ๋๋ Tailwind ๋ ์ด์ด์ ์ถ๊ฐ */
code[data-theme*=' '] {
@apply grid min-w-full break-words rounded-none border-l-4 border-l-transparent bg-transparent py-1;
}
/* ํ์ด๋ผ์ดํธ๋ ๋ผ์ธ ์คํ์ผ */
div[data-rehype-pretty-code-fragment] span[data-highlighted-line] {
@apply border-l-blue-500 bg-blue-500/10;
}
/* ์ฝ๋ ๋ธ๋ก ์ ๋ชฉ ์คํ์ผ */
div[data-rehype-pretty-code-title] {
@apply mt-4 rounded-t-lg bg-slate-800 px-4 py-2 text-sm font-medium text-slate-200;
}5. ๊ฒฐ๋ก
remark-gfm์ผ๋ก ๋ฌธ์์ ๊ตฌ์กฐ๋ฅผ ์ก๊ณ , rehype-pretty-code๋ก ์ฝ๋ ๊ฐ๋
์ฑ์ ๋์ด๋ฉด ๊ธฐ์ ๋ธ๋ก๊ทธ์ ํ์ง์ด ํ์ธต ์ฌ๋ผ๊ฐ๋๋ค. ํนํ Shiki ๊ธฐ๋ฐ์ ์ ์ ํ์ด๋ผ์ดํ
์ ๋ฐํ์ ์ค๋ฒํค๋๊ฐ ์์ด ์ฑ๋ฅ ๋ฉด์์๋ ์ฐ์ํฉ๋๋ค.