はじめに
Markdownって便利ですよね。このブログもMarkdownで書いているんですが、これをWebサイトで表示するにはHTMLに変換する必要があります。
そこで登場するのがMarkedというライブラリ。正直なところ、MarkdownパーサーはいくつかあるんですがMarkedは「速さ」と「軽さ」を両立している点で、個人的にはかなり推しています。
2011年から開発が続いている老舗ライブラリで、GitHub上では34,000スター以上を獲得。週間ダウンロード数は900万を超えるという、まさにMarkdownパーサーの定番といえる存在なんですよね。
Markedの特徴・メリット
1. とにかく高速
Markedは「low-level markdown compiler」として設計されています。キャッシングやブロッキングなしで解析を行うため、処理速度が非常に速い。大量のMarkdownファイルを扱う場面でも、パフォーマンスの心配をしなくて済むのは大きいですね。
2. 高い仕様準拠率
- Markdown 1.0: 100%対応
- CommonMark 0.31: 98%対応
- GitHub Flavored Markdown 0.29: 97%対応
GFM対応なので、テーブルやタスクリスト、取り消し線なんかも普通に使えます。GitHubのREADMEで書いたMarkdownがそのまま動くのは、地味にありがたい。
3. 環境を選ばない
ブラウザでもNode.jsでも、CLIでも動作します。フロントエンドでリアルタイムプレビューを作りたいときも、ビルド時に静的HTMLを生成したいときも、同じライブラリで対応できるのはメンテナンス的にも楽なんですよね。
4. 軽量で依存関係が少ない
余計な依存パッケージがほとんどないので、bundle sizeを気にするプロジェクトでも安心して導入できます。
インストール方法
npmでインストール
npm install marked
CLIとして使う場合
npm install -g marked
CDNから読み込む場合
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
基本的な使い方
Node.jsでの使用
import { marked } from 'marked';
const markdown = `
# タイトル
これは**太字**で、これは*イタリック*です。
- リスト1
- リスト2
- リスト3
`;
const html = marked.parse(markdown);
console.log(html);
ブラウザでの使用
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
<div id="content"></div>
<script>
const markdown = '# Hello World\n\nMarkedで変換しました。';
document.getElementById('content').innerHTML = marked.parse(markdown);
</script>
</body>
</html>
CLIでの使用
# ファイルを変換
marked -i readme.md -o readme.html
# 標準入力から変換
echo "# Hello" | marked
実践的なユースケース
GFMオプションを有効にしてテーブルを使う
import { marked } from 'marked';
marked.setOptions({
gfm: true, // GitHub Flavored Markdown
breaks: true, // 改行をbrタグに変換
});
const tableMarkdown = `
| 機能 | Marked | 他のライブラリ |
|------|--------|---------------|
| 速度 | 高速 | 普通 |
| サイズ | 軽量 | 重い |
`;
console.log(marked.parse(tableMarkdown));
シンタックスハイライトとの連携
コードブロックにシンタックスハイライトを適用したい場合は、highlight.jsなどと組み合わせます。
import { marked } from 'marked';
import hljs from 'highlight.js';
marked.setOptions({
highlight: function(code, lang) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value;
}
return code;
}
});
カスタムレンダラーで出力をカスタマイズ
リンクを新しいタブで開くようにする例です。
import { marked } from 'marked';
const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
const titleAttr = title ? ` title="${title}"` : '';
return `<a href="${href}"${titleAttr} target="_blank" rel="noopener noreferrer">${text}</a>`;
};
marked.setOptions({ renderer });
セキュリティ対策
これ、意外と見落としがちなんですが、Markedは出力HTMLのサニタイズを自動では行いません。ユーザー入力を扱う場合は、必ずDOMPurifyなどでサニタイズしましょう。
import { marked } from 'marked';
import DOMPurify from 'dompurify';
const unsafeMarkdown = userInput; // ユーザーからの入力
const rawHtml = marked.parse(unsafeMarkdown);
const safeHtml = DOMPurify.sanitize(rawHtml);
document.getElementById('content').innerHTML = safeHtml;
XSS対策は30代エンジニアとして、もう当たり前のように意識しておきたいところですね。
まとめ
Markedは、MarkdownをHTMLに変換するライブラリとしては、正直一択と言っていいくらいの完成度だと思います。
- 高速で軽量
- 主要なMarkdown仕様にほぼ100%対応
- ブラウザ・Node.js・CLIどこでも動く
- カスタマイズ性も高い
ブログシステムやドキュメントサイトを作るとき、Markdownエディタのプレビュー機能を実装するとき、README.mdをWebページに表示したいときなど、使いどころは多いですね。
10年以上メンテナンスが続いている安定感も、本番環境で使うライブラリ選びでは重要なポイント。個人的には、Markdownを扱う案件では真っ先に検討するライブラリです。
公式サイト: https://marked.js.org/