remark-gfm でGitHub風マークダウンを実装する方法
基本セットアップ
インストール
# 基本パッケージ
npm install remark remark-gfm remark-html
# React使用時
npm install remark-react
基本設定
import { remark } from 'remark';
import remarkGfm from 'remark-gfm';
import remarkHtml from 'remark-html';
const processor = remark()
.use(remarkGfm)
.use(remarkHtml);
Next.js での実装
MDX プロジェクトでの設定
// next.config.js
import remarkGfm from 'remark-gfm';
const nextConfig = {
experimental: {
mdxRs: true,
},
pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
};
export default nextConfig;
ブログ記事の処理
// lib/markdown.js
import fs from 'fs';
import path from 'path';
export async function getPostContent(slug) {
const fullPath = path.join('posts', `${slug}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const processedContent = await remark()
.use(remarkGfm)
.use(remarkHtml)
.process(fileContents);
return processedContent.toString();
}
React コンポーネントでの活用
マークダウンレンダラー
// components/MarkdownRenderer.jsx
import { useEffect, useState } from 'react';
import { remark } from 'remark';
import remarkGfm from 'remark-gfm';
import remarkReact from 'remark-react';
export default function MarkdownRenderer({ content }) {
const [result, setResult] = useState(null);
useEffect(() => {
remark()
.use(remarkGfm)
.use(remarkReact)
.process(content)
.then((file) => setResult(file.result));
}, [content]);
return <div className="markdown-content">{result}</div>;
}
GFM 機能の活用例
表とタスクリスト
| 機能 | 対応状況 |
|------|----------|
| 表組み | ✅ |
| タスクリスト | ✅ |
| 削除線 | ✅ |
- [x] remark-gfm インストール
- [x] 基本設定完了
- [ ] スタイリング調整
よくあるエラーと対処法
// エラー: remark processor が未定義
// 解決: async/await の適切な使用
async function processMarkdown(content) {
try {
const result = await remark()
.use(remarkGfm)
.use(remarkHtml)
.process(content);
return result.toString();
} catch (error) {
console.error('Markdown processing failed:', error);
return '';
}
}
スタイリングの最適化
CSS での表スタイル
/* styles/markdown.css */
.markdown-content table {
border-collapse: collapse;
width: 100%;
margin: 1rem 0;
}
.markdown-content th,
.markdown-content td {
border: 1px solid #ddd;
padding: 8px 12px;
text-align: left;
}
.markdown-content th {
background-color: #f5f5f5;
font-weight: 600;
}
パフォーマンス最適化
メモ化とキャッシュ
// utils/markdownCache.js
const cache = new Map();
export async function processWithCache(content) {
const hash = createHash(content);
if (cache.has(hash)) {
return cache.get(hash);
}
const result = await remark()
.use(remarkGfm)
.use(remarkHtml)
.process(content);
const output = result.toString();
cache.set(hash, output);
return output;
}
package.json スクリプト例
{
"scripts": {
"markdown:build": "node scripts/build-markdown.js",
"markdown:watch": "chokidar 'content/**/*.md' -c 'npm run markdown:build'"
}
}
トラブルシューティング
よくある問題
-
表が正しく表示されない
- CSS の table スタイルを確認
- markdown の表記法をチェック
-
タスクリストがレンダリングされない
- remark-gfm の読み込み順序を確認
- プラグインのバージョン互換性をチェック
-
削除線が効かない
~~の記法が正しいか確認- CSS で
text-decoration: line-throughを設定
参考資料
remark 15.x および remark-gfm 4.x を基準としています。