Статическая генерация

Библиотека Marked является мощным инструментом для парсинга Markdown в JavaScript. Она позволяет превращать Markdown-текст в HTML с высокой скоростью и гибкостью. Основная задача библиотеки — преобразование синтаксиса Markdown в корректный HTML, который можно использовать на веб-страницах или в статических генераторах сайтов.

import { marked } from 'marked';

const markdown = `# Заголовок первого уровня
Это пример текста с **жирным** и *курсивным* форматированием.`;

const html = marked(markdown);
console.log(html);

В этом примере Markdown-текст преобразуется в HTML. marked() возвращает строку HTML, готовую к вставке в DOM или сохранению в файле.


Конфигурация и опции

Marked поддерживает широкие возможности настройки. Основные опции включают:

  • gfm — включает поддержку GitHub Flavored Markdown (по умолчанию true).
  • breaks — вставка <br> при переносах строк (false по умолчанию).
  • smartLists — улучшенные списки с автоматическим определением нумерации (true по умолчанию).
  • sanitize — удаление потенциально опасного HTML (false по умолчанию).

Пример использования настроек:

marked.setOptions({
  gfm: true,
  breaks: true,
  smartLists: true,
  sanitize: true
});

const html = marked('# Пример с настройками');
console.log(html);

Создание собственного рендерера

Для полного контроля над генерацией HTML можно использовать Custom Renderer. Это позволяет переопределять поведение преобразования отдельных элементов Markdown, например, заголовков, ссылок или изображений.

const renderer = new marked.Renderer();

renderer.heading = (text, level) => {
  return `<h${level} class="custom-heading">${text}</h${level}>`;
};

renderer.link = (href, title, text) => {
  return `<a href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
};

const markdown = '# Заголовок\n[Ссылка](https://example.com)';
const html = marked(markdown, { renderer });
console.log(html);

Особенности кастомного рендерера:

  • Позволяет добавлять CSS-классы или атрибуты к элементам.
  • Поддерживает любые HTML-теги вместо стандартных.
  • Совместим с расширениями Markdown.

Использование токенизации

Marked предоставляет API для лексического анализа Markdown, позволяя работать с токенами перед генерацией HTML. Это важно для статической генерации, где необходим контроль над структурой документа.

const tokens = marked.lexer('# Заголовок\nТекст с **жирным**');
console.log(tokens);

Возвращаемый объект содержит массив токенов с типами (heading, paragraph, strong) и значениями. Это позволяет:

  • Фильтровать определённые элементы Markdown.
  • Создавать таблицы содержимого или оглавление.
  • Применять дополнительные стили или логику до конвертации в HTML.

Применение в статических генераторах

Для статической генерации веб-страниц Marked подходит идеально:

  1. Чтение Markdown-файлов: использование fs.readFileSync или асинхронных функций.
  2. Преобразование Markdown в HTML с помощью marked().
  3. Интеграция с шаблонами: вставка HTML-контента в статические шаблоны страниц.

Пример генерации страницы:

import fs from 'fs';
import { marked } from 'marked';

const markdown = fs.readFileSync('./content/post.md', 'utf-8');
const htmlContent = marked(markdown);

const template = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Статическая страница</title>
</head>
<body>
  ${htmlContent}
</body>
</html>
`;

fs.writeFileSync('./dist/post.html', template);

Этот подход обеспечивает полностью статический HTML, который можно размещать на любом сервере без необходимости исполнения JavaScript на клиенте.


Расширение функционала через плагины

Marked поддерживает custom tokenizer и custom renderer, что открывает возможности для создания собственных расширений Markdown. Примеры расширений:

  • Автоматическая генерация таблицы содержимого (toc).
  • Преобразование специальных синтаксисов, например @[user] в ссылки на профиль.
  • Поддержка диаграмм или блоков кода с подсветкой синтаксиса.
const renderer = new marked.Renderer();

renderer.code = (code, language) => {
  return `<pre class="code-block"><code class="${language}">${code}</code></pre>`;
};

Поддержка асинхронных операций

Marked предоставляет асинхронный API, что позволяет обрабатывать большие Markdown-документы и интегрировать асинхронные операции, например, загрузку внешних данных или вставку контента.

import { marked } from 'marked';

async function generateHTML(markdown) {
  return await marked.parse(markdown);
}

const html = await generateHTML('# Асинхронная обработка');
console.log(html);

Асинхронная обработка особенно полезна при генерации сайтов с динамическим контентом, когда Markdown собирается из разных источников.


Советы по производительности

  • Использовать marked.parse вместо marked() для больших файлов, так как новый API оптимизирован под высокую производительность.
  • Включать gfm: true только при необходимости, чтобы ускорить парсинг.
  • Кэшировать результат конвертации Markdown в HTML при повторной генерации страницы.

Marked сочетает скорость, гибкость настройки и широкие возможности расширения, что делает его одним из лучших инструментов для статической генерации контента в JavaScript.