Skip to content

vitepress-plugin-export

Генерация экспортных файлов документации (PDF, HTML, EPUB) после vitepress build. Плагин обходит все страницы версий из сайдбара, собирает единый документ с оглавлением и сохраняет результат в директорию dist.

Что умеет:

  • Генерирует PDF через Chromium/Chrome с точными закладками (использует named destinations из PDF, созданные Chrome)
  • Генерирует автономный HTML с инлайновым CSS
  • Генерирует EPUB 3 с иерархическим оглавлением и работающими внутренними ссылками
  • Определяет версии автоматически по ключам сайдбара (/11.2/, /11.1/ и т.д.)
  • Пишет export-manifest.json для компонента ExportButton в теме
  • Раздаёт готовые файлы через dev-сервер VitePress

Установка

bash
pnpm add -D @ampernic/vitepress-plugin-export

Для PDF нужен Chromium или Chrome в системе, а также puppeteer-core (peer / devDependency проекта документации):

bash
pnpm add -D puppeteer-core

jszip, pdf-lib и picocolors идут как обычные зависимости самого плагина - отдельно ставить не нужно.

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

Через createSharedConfig (рекомендуется)

При использовании @ampernic/vitepress-theme-alt-docs достаточно передать опцию export:

ts
// .vitepress/config/index.mts
import { createSharedConfig } from '@ampernic/vitepress-theme-alt-docs/config'
import { sidebar } from './sidebar'

const shared = createSharedConfig({
  distroName: 'alt-kworkstation',
  export: {
    sidebar,
    distroName: 'alt-kworkstation',
    formats: ['pdf', 'html', 'epub'],
    tocDepth: 2,
  },
})

Напрямую в VitePress config

ts
// .vitepress/config.mts
import { defineConfig } from 'vitepress'
import { ExportPlugin } from '@ampernic/vitepress-plugin-export'
import { sidebar } from './sidebar'

const exportPlugin = ExportPlugin({
  sidebar,
  distroName: 'alt-kworkstation',
  formats: ['pdf', 'html', 'epub'],
})

export default defineConfig({
  buildEnd: async () => {
    await exportPlugin.buildEnd()
  },
  vite: {
    plugins: [...exportPlugin.vite.plugins],
  },
})

Опции

ОпцияТипПо умолчаниюОписание
sidebarSidebarMulti-Сайдбар VitePress (обязательно)
distroNamestring-Slug дистрибутива, используется в именах файлов
formats('pdf' | 'html' | 'epub')[]['pdf']Форматы для генерации
versionsstring[]автоВерсии; если не указано - берутся из ключей сайдбара
outDirstring.vitepress/distДиректория собранного сайта
basestringиз ViteBase URL сайта
executablePathstringиз env/системыПуть к Chromium/Chrome (для PDF)
skipbooleanfalseПропустить генерацию (удобно в dev)
tocDepthnumber2Максимальная глубина текстового оглавления
outlineDepthnumbertocDepth + 1Глубина закладок / EPUB nav (независимо от tocDepth) - можно оставить компактное «Содержание», но пустить закладки на уровень глубже
waitUntilstring'load'Puppeteer waitUntil (для PDF)
pagesLimitnumber-Лимит страниц на версию (для отладки)
concurrencynumber6Сколько версий строить параллельно (форматы внутри версии тоже идут одновременно)
shareBrowserbooleantrueИспользовать общий пул Chromium вместо запуска процесса на каждый PDF. Отключается только на очень тяжёлых сборках (false)
chromiumPoolSizenumbermin(3, concurrency)Сколько Chromium держать в пуле; страницы одного слота делят браузер, разные слоты - разные браузеры
logoLinkstring-URL, в который оборачивается лого титульной страницы PDF/HTML. При использовании createSharedConfig подставляется автоматически из productLinks[distroName]
debugbooleanfalseПодробный лог

Именование файлов

Файлы сохраняются в корень outDir:

  • {distroName}-{version}.pdf - например alt-kworkstation-11.2.pdf
  • {distroName}-{version}.html - например alt-kworkstation-11.2.html
  • {distroName}-{version}.epub - например alt-kworkstation-11.2.epub

Если distroName не указан: export-{version}.pdf и т.д.

Компонент кнопки скачивания

Плагин включает Vue-компонент ExportButton, который читает export-manifest.json и показывает выпадающее меню для скачивания. В теме vitepress-theme-alt-docs он подключён автоматически в слот aside-outline-after.

Для ручного подключения:

ts
// .vitepress/theme/index.ts
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import ExportButton from '@ampernic/vitepress-plugin-export/components/ExportButton.vue'

export default {
  extends: DefaultTheme,
  Layout() {
    return h(DefaultTheme.Layout, null, {
      'aside-outline-after': () => h(ExportButton),
    })
  },
}

Как работает PDF

  1. Все страницы версии объединяются в один HTML-документ с оглавлением
  2. Документ открывается в Chromium через Puppeteer и печатается в PDF
  3. После генерации PDF считываются GoTo-аннотации (named destinations), которые Chrome создал для ссылок оглавления
  4. Из этих аннотаций строится иерархическое дерево закладок (outline) и вставляется в PDF через pdf-lib

Обложка / лого

Cover-блок PDF/HTML ищет файл branding/{distroName}/logo-col.svg в собранном dist (VitePress копирует docs/public/branding/... как есть). Если файл найден - вставляется в верх обложки перед h1. Если нет - обложка получает только заголовок. Для растровых логотипов допустимо обернуть PNG в SVG-контейнер с <image href="data:image/png;base64,..."> - тот же файл сохраняет расширение .svg и подхватывается без правок плагина.

Part-landing TOC dedup

Part-страница, у которой контент - только автогенерированное «Содержание» (конвертер эмитит его для part-контейнеров, где inline <chapter> теперь живут отдельными страницами), уже содержит <h2>Содержание</h2> со списком глав. Плагин injectPartToc проверяет наличие такого заголовка в HTML и НЕ добавляет второй блок - иначе PDF/EPUB рендерил бы «Содержание» дважды подряд.

Хромиум

Плагин ищет Chromium в порядке:

  1. executablePath в опциях
  2. PUPPETEER_EXECUTABLE_PATH env
  3. Стандартные системные пути (/usr/bin/chromium-browser, /usr/bin/google-chrome и т.д.)