Для начала работы с библиотекой Marked в серверной среде Node.js необходимо установить её через npm:
npm install marked
После установки библиотеку подключают стандартным способом:
const { marked } = require('marked');
В случае использования ES-модулей:
import { marked } from 'marked';
Основной функционал библиотеки заключается в конвертации текста из
Markdown в HTML. Для этого используется функция
marked():
const markdownText = `
# Заголовок уровня 1
Это **жирный** текст и *курсив*.
`;
const html = marked(markdownText);
console.log(html);
В результате получится HTML с корректной структурой тегов
<h1>, <strong> и
<em>.
Marked предоставляет гибкую систему конфигурации через объект опций,
который передаётся в marked.setOptions():
marked.setOptions({
gfm: true, // включение GitHub Flavored Markdown
breaks: false, // перенос строк по Enter
smartLists: true, // умные списки
smartypants: true, // преобразование кавычек и дефисов в типографские символы
headerIds: true, // генерация id для заголовков
});
Эти опции позволяют адаптировать рендеринг под конкретные требования проекта.
Marked позволяет создавать пользовательский рендерер, чтобы полностью контролировать генерацию HTML. Например:
const renderer = new marked.Renderer();
renderer.heading = function (text, level) {
return `<h${level} class="custom-header">${text}</h${level}>`;
};
const htmlCustom = marked('# Тестовый заголовок', { renderer });
console.log(htmlCustom);
В этом примере заголовки будут рендериться с классом
custom-header, что удобно для стилизации на сервере перед
отправкой клиенту.
Для проектов с небезопасным Markdown (например, полученным от
пользователей) важно использовать асинхронный рендеринг
с возможностью фильтрации HTML через sanitize или
интеграцию с библиотеками вроде DOMPurify:
import DOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
const window = (new JSDOM('')).window;
const DOMPurifyInstance = DOMPurify(window);
const unsafeMarkdown = 'Пример с <script>alert("XSS")</script>';
const safeHtml = DOMPurifyInstance.sanitize(marked(unsafeMarkdown));
Такой подход предотвращает выполнение вредоносного кода при серверной генерации HTML.
Для работы с большим объемом Markdown эффективнее использовать токены и потоки:
const lexer = new marked.Lexer();
const tokens = lexer.lex(largeMarkdownText);
tokens.forEach(token => {
// обработка каждого токена
});
const html = marked.parser(tokens);
Разделение на лексический и синтаксический этап позволяет оптимизировать производительность и контролировать процесс рендеринга на сервере.
Marked легко интегрируется с Express.js, Koa и другими серверными платформами. Пример middleware для Express:
app.post('/render', (req, res) => {
const markdown = req.body.markdown || '';
const html = marked(markdown);
res.send(html);
});
Такой подход позволяет серверу динамически преобразовывать Markdown в HTML для веб-страниц или API.
Настройки рендерера позволяют кастомизировать генерацию ссылок, изображений и таблиц:
renderer.link = function(href, title, text) {
return `<a href="${href}" target="_blank" rel="noopener">${text}</a>`;
};
renderer.image = function(href, title, text) {
return `<img src="${href}" alt="${text}" loading="lazy">`;
};
Использование target="_blank" и
rel="noopener" повышает безопасность при открытии внешних
ссылок.
Marked поддерживает GFM-специфичные элементы: таблицы, чекбоксы, автоматические ссылки. Пример:
marked.setOptions({ gfm: true });
const markdown = `
- [x] Выполнено
- [ ] В процессе
| Имя | Возраст |
|-----|---------|
| Анна | 25 |
| Борис | 30 |
`;
const html = marked(markdown);
Для больших проектов с повторяющимся контентом имеет смысл кешировать результат рендеринга Markdown в HTML:
const cache = new Map();
function renderMarkdown(markdown) {
if (cache.has(markdown)) {
return cache.get(markdown);
}
const html = marked(markdown);
cache.set(markdown, html);
return html;
}
Это снижает нагрузку на сервер и ускоряет отдачу страниц.
Marked обеспечивает высокопроизводительный и гибкий серверный рендеринг Markdown, поддерживает асинхронную обработку, безопасный HTML, кастомизацию рендерера и интеграцию с серверными фреймворками. Продуманное использование токенов, кэширования и опций позволяет создавать масштабируемые и безопасные веб-приложения.