Рендеринг Shadow DOM и шаблонов в Puppeteer

Рендеринг веб-компонентов на стороне сервера с помощью Google Puppeteer — непростая задача. Сериализация Shadow DOM находится на экспериментальной стадии. Декларативное теневое DOM позволяет сериализовать теневое DOM и может быть включено с помощью нескольких простых шагов. Без выполнения этих шагов у вас останутся пустые пользовательские элементы после рендеринга в Puppeteer.

Включить теневой корень

Чтобы ваш Shadow DOM был сериализован с экспериментальными функциями, вам сначала нужно установить свойство shadowroot шаблона.

<template shadowroot="open">

Включить экспериментальные функции веб-платформы

Чтобы сериализовать Shadow DOM в Puppeteer, мы собираемся использовать предложенную новую функцию для элементов: getInnerHTML. Эта функция принимает объект, который выставил свойство includeShadowRoots.

const html = await page.$eval('html', (element) => {
    return element.getInnerHTML({includeShadowRoots: true});
});

Эта функция не определена без включенных экспериментальных функций. Чтобы включить эту функцию в своем браузере, перейдите по ссылке: chrome://flags/#enable-experimental-web-platform-features. Чтобы включить эту функцию в Puppeteer, вы должны изменить конфигурацию запуска:

const args = puppeteer.defaultArgs();
// IMPORTANT: you can't render shadow DOM without this flag
// getInnerHTML will be undefined without it
args.push('--enable-experimental-web-platform-features');
const browser = await puppeteer.launch({
    args
});

Определение метода ожидания

Чтобы результаты выполнения вашего компонента были включены в вывод, вам нужно дождаться завершения рендеринга. Для этого мы запрашиваем DOM, чтобы обнаружить наличие теневого корня.

await page.waitForFunction(selector => !!document.querySelector(selector)?.shadowRoot, {
    polling: 'mutation',
}, selector);

Для получения дополнительной информации о waitForFunction нажмите здесь.

Полный пример

Полный функциональный пример приведен ниже. Если вы застряли, пытаясь отобразить веб-компоненты, скопируйте пример и протестируйте его. Удачного кодирования!