# Практические сценарии

# Как добавить сторонние плагины в Styleguidist?

Styleguidist не загружает файл main.js. Чтобы установить плагины и библиотеки компонентов, подключите их отдельно.

# Vue 3

Сначала создайте файл .js, который установит плагины в существующее приложение Vue. Затем добавьте его в параметр enhancePreviewApp файла styleguide.config.js:

styleguide.config.js

module.exports = {
  enhancePreviewApp: [path.join(__dirname, 'styleguide/global.requires.js')]
}

styleguide/global.requires.js

import VCalendar from "v-calendar"
import "v-calendar/style.css"

export default function (app) {
  app.use(VCalendar, {})
}

# Vue 2

Сначала создайте файл .js, который устанавливает плагины. Затем добавьте его в параметр require файла styleguide.config.js:

styleguide.config.js

module.exports = {
  require: [path.join(__dirname, 'styleguide/global.requires.js')]
}

styleguide/global.requires.js

import Vue from 'vue'
import VeeValidate from 'vee-validate'
import VueI18n from 'vue-i18n'
// import full version fo vuetify (see NOTE)
import Vuetify from 'vuetify'
// get the exported options from the plugin to avoid rewriting them
import { opts } from '../src/plugins/vuetify'

Vue.use(VueI18n)
Vue.use(VeeValidate)
Vue.use(Vuetify, opts)

# Изменение корневого компонента примеров предварительного просмотра

Если вам нужно изменить корневой компонент каждого из вариантов предварительного просмотра, вы можете изменить корневой компонент предварительного просмотра. Создание файла .js, который экспортирует корневой компонент как компонент jsx (opens new window), а затем добавляет его в файл styleguide.config.js.

Используйте опцию renderRootJsx:

// config/styleguide.root.js
import VueI18n from 'vue-i18n'
import Vuetify from 'vuetify'
import messages from './i18n'

const i18n = new VueI18n({
  locale: 'en',
  messages
})

export default previewComponent => {
  // https://vuejs.org/v2/guide/render-function.html
  return {
    i18n,
    // let's not forget to add all necessary info to
    // each vue app root about vuetify
    vuetify: new Vuetify(),
    render(createElement) {
      // v-app to support vuetify plugin
      return createElement('v-app', [createElement(previewComponent)])
    }
  }
}
// styleguide.config.js
module.exports = {
  renderRootJsx: path.join(__dirname, 'config/styleguide.root.js')
}

См. пример style guide with vuetify and vue-i18n (opens new window).

Примечание: поскольку Styleguidist использует отдельный корневой инстанс для каждого примера, стандартная установка Vuetify может не сработать. Рекомендуется глобальная регистрация, как показано выше.

# Как добавить Vuex в Styleguidist?

Создайте .js-файл, подключите Vuex и укажите его в styleguide.config.js.

// config/styleguide.root.js
import Vue from 'vue'
import Vuex from 'vuex'
import { state, mutations, getters } from './mutations'

Vue.use(Vuex)

const store = new Vuex.Store({
  state,
  getters,
  mutations
})

export default previewComponent => {
  // https://vuejs.org/v2/guide/render-function.html
  return {
    store,
    render(createElement) {
      return createElement(previewComponent)
    }
  }
}

Используйте опцию require:

// styleguide.config.js
module.exports = {
  renderRootJsx: path.join(__dirname, 'config/styleguide.root.js')
}

См. пример style guide with vuex (opens new window).

# Как добавить тестовые данные в Styleguidist?

Можно использовать global mixins (opens new window) для добавления тестовых данных:

Используйте опцию require:

// styleguide/global.requires.js
import Vue from 'vue'

Vue.mixin({
  data() {
    return {
      colorDemo: 'blue',
      sizeDemo: 'large'
    }
  }
})
// styleguide.config.js
module.exports = {
  require: [path.join(__dirname, 'styleguide/global.requires.js')]
}
// example component

<Button size="colorDemo" color="sizeDemo">
  Click Me
</Button>

# Как исключить некоторые компоненты из Styleguidist?

Vue Styleguidist по умолчанию игнорирует тесты (папка __tests__).

Используйте опцию ignore, чтобы настроить такое поведение:

module.exports = {
  ignore: ['**/*.spec.vue', '**/components/Button.vue']
}

Примечание. Используйте glob-шаблоны, например **/components/Button.vue вместо components/Button.vue.

# Как скрыть некоторые компоненты в Styleguidist, но оставить их доступными в примерах?

  • Если мы не используем locallyRegisterComponents, все документированные компоненты доступны в каждом примере. Если мы создадим компоненты из боковой панели и документации, используя конфигурацию ignore, они получатся для примера. Используйте опцию require, чтобы загрузить файл, в котором мы будем регистрировать наши скрытые компоненты.

# Конкретный пример:

Проблема: Я не хочу документировать ни один компонент, имя файла которого начинается с подчеркивания (_).

module.exports = {
  // load install.components.js for every page and example
  require: ['./docs/install.components.js'],
  // register all the components
  components: 'src/components/**/*.vue',
  // avoid documenting components that start with _
  ignore: ['**/_*.vue']
}

Если вы начали с vue-cli или только что установили Styleguidist, файла docs/install.components.js в проекте может не быть.

ПРИМЕЧАНИЕ docs/install.components.js выше — это имя файла, который мы выбрали. Не важно, какое имя вы выберете, поэтому выберите то, которое имеет для вас смысл.

Сначала мы создаем docs/install.components.js. Затем мы будем использовать функцию узла 6 require (или require.context, поскольку мы находимся в двадцатом веб-пакете), чтобы собрать компоненты, которые мы хотим использовать в примерах.

Наконец, мы регистрируем их с помощью функции Vue.component().

Компоненты, начинающиеся с подчеркивания, теперь доступны в каждом примере (без подчеркивания).

import Vue from 'vue'
import * as path from 'path'

const registerAllComponents = components => {
  // For each matching file name...
  components.keys().forEach(fileName => {
    // Get the component config
    const componentConfig = components(fileName)

    // get the component name from the object
    const componentName =
      componentConfig.default.name ||
      componentConfig.name ||
      // or from the filename, removing any character
      // that would not fit in a component name
      path.basename(fileName, '.vue').replace(/[^0-9a-zA-Z]/, '')

    // Globally register the component
    Vue.component(
      componentName,
      componentConfig.default || componentConfig
    )
  })
}

// register all components with a file name starting with _
registerAllComponents(
  require.context('../src/', true, /[\\/]_.+\.vue$/)
)

# Как добавить собственный JavaScript, CSS или полифилы?

В вашей конфигурации Styleguidist:

const path = require('path')
module.exports = {
  require: [
    'babel-polyfill',
    path.join(__dirname, 'path/to/script.js'),
    path.join(__dirname, 'path/to/styles.css')
  ]
}

# Как изменить стили Styleguidist?

Для настройки интерфейса Styleguidist используйте две опции: theme и styles.

Используйте theme, чтобы изменить шрифты, цвета и т. д. д. д. д.

Используйте styles для настройки стиля любого компонента Styleguidist.

В качестве примера:

module.exports = {
  theme: {
    color: {
      link: 'firebrick',
      linkHover: 'salmon'
    },
    fontFamily: {
      base: '"Comic Sans MS", "Comic Sans", cursive'
    }
  },
  styles: {
    Logo: {
      // We're changing the LogoRenderer component
      logo: {
        // We're changing the rsg--logo-XX class name inside the component
        animation: 'blink ease-in-out 300ms infinite'
      },
      '@keyframes blink': {
        to: { opacity: 0 }
      }
    }
  }
}

Примечание: См. доступный theme variables (opens new window).

Примечание. В стилях используется JSS (opens new window) с учетом плагинов: jss-isolate (opens new window), jss-nested (opens new window), jss-camel-case (opens new window), jss-default-unit (opens new window), jss-compose (opens new window) и jss-global (opens new window).

Примечание. Используйте React Developer Tools (opens new window) для поиска названных компонентов и стилей. Например, компонент <LogoRenderer><h1 className="rsg--logo-53"> соответствует приведенному выше примеру.

Примечание. Используйте функцию вместо объекта для styles, чтобы получить доступ ко всем переменным темам в ваших обычных стилях.

module.exports = {
  styles: function (theme) {
    return {
      Logo: {
        logo: {
          // we can now change the color used in the logo item to use the theme's `link` color
          color: theme.color.link
        }
      }
    }
  }
}

ПРИМЕЧАНИЕ. Если нужно сослаться на исходный компонент, импортируйте версию rsg-components-default. Например, customized (opens new window) использует следующий подход:

// SectionsRenderer.js
import React from 'react'
import PropTypes from 'prop-types'
import Styled from 'rsg-components/Styled'
import Heading from 'rsg-components/Heading'

// Avoid circular ref
// Import default implementation using `rsg-components-default`
import DefaultSectionsRenderer from 'rsg-components-default/Sections/SectionsRenderer'

const styles = ({ fontFamily, color, space }) => ({
  headingSpacer: {
    marginBottom: space[2]
  },
  descriptionText: {
    marginTop: space[0],
    fontFamily: fontFamily.base
  }
})

export function SectionsRenderer({ classes, children }) {
  return (
    <div>
      {!!children.length && (
        <div className={classes.headingSpacer}>
          <Heading level={1}>Example Components</Heading>
          <p className={classes.descriptionText}>
            These are the greatest components
          </p>
        </div>
      )}
      <DefaultSectionsRenderer>{children}</DefaultSectionsRenderer>
    </div>
  )
}

SectionsRenderer.propTypes = {
  classes: PropTypes.object.isRequired,
  children: PropTypes.node
}

export default Styled(styles)(SectionsRenderer)

# Как изменить вывод логов dev-сервера Styleguidist?

Вы можете изменить формат журналов сервера разработки веб-пакета, изменив параметр stats конфигурации веб-пакета:

module.exports = {
  webpackConfig(env) {
    if (env === 'development') {
      return {
        stats: {
          chunks: false,
          chunkModules: false,
          chunkOrigins: false
        }
      }
    }
    return {}
  }
}

# Как отлаживать мои компоненты и примеры?

  1. Откройте инструменты разработчика вашего браузера.
  2. Напишите оператору debugger;, где вы хотите: в исходном коде компонента, в формате Markdown или даже в редакторе браузера.

# Как отладить исключения, возникающие из моих компонентов?

  1. Поместите оператора debugger; в начало вашего кода. Нажмите кнопку Отладчик в инструментах разработчика вашего браузера. Нажмите кнопку Продолжить и отладчик заблокирует запуск JavaScript в браузере при следующем отключении.

# Как использовать Vagrant со Styleguidist?

Сначала прочитайте Vagrant guide (opens new window) из документации веб-пакета. Затем опрос в конфигурации вашего веб-пакета:

devServer: {
  watchOptions: {
    poll: true
  }
}

# Как документировать стилизованные компоненты?

Чтобы документировать стилизованные компоненты, вам необходимо, чтобы они распознавали vue-docgen-api. Самый простой способ — использовать расширения:

import styled from 'vue-styled-components'

const _StyledTitle = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`

export default {
  extends: _StyledTitle
}

или если вы используете синтаксис компонента класса

import styled from 'vue-styled-components'

const _StyledTitle = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`

@Components({ extends: _StyledTitle })
export default class StyledTitle extends Vue {}

# Как использовать Vue Styleguidist с компонентами, содержащими маршрутизацию?

Если ваши компоненты содержат <router-link>, в примерах Styleguidist лучше подменить его упрощенным компонентом. Для этого добавьте файл styleguide.global.requires.js (пример ниже) и подключите его через опцию require. Не подключайте vue-router напрямую внутри Styleguidist.

// styleguide.global.requires.js
import Vue from 'vue'
Vue.component('RouterLink', {
  props: {
    tag: { type: String, default: 'a' }
  },
  render(createElement) {
    return createElement(this.tag, {}, this.$slots.default)
  }
})

См. этот пример для полной реализации.

Совет: если в браузерной консоли видны ошибки .resolve, скорее всего, где-то все еще подключается vue-router.

  1. Найдите все вхождения Vue.use(Router) в кодовой базе.
  2. Добавьте перед ними console.trace(), чтобы увидеть стек вызовов.
  3. Уберите лишнее подключение роутера из кода, используемого в примерах.

Если полностью убрать подключение нельзя, можно включать его условно: установите пакет cross-env, запускайте Styleguidist как cross-env MYSTYLE=true styleguide serve и проверяйте переменную в коде.

> if (!process.env.MYSTYLE) {
>   Vue.use(Router)
> }
> ```

## Как включить FontAwesome (или другие наборы иконок) в Styleguidist?

Если ваши компоненты используют набор значков, например FontAwesome, вы можете отредактировать `styleguide.config.js`, чтобы импортировать его:

```js
module.exports = {
  title: "Мой Styleguidist",
  template: {
    head: {
      links: [
        {
          rel: 'stylesheet',
          href:
            'https://pro.fontawesome.com/releases/v5.8.2/css/all.css',
          integrity: 'your hash here',
          crossorigin: 'anonymous'
        }
      ]
    }
  }
}

Дополнительную информацию см. в template.

# Как использовать Vue Styleguidist с несколькими пакетами компонентов?

Если ваши базовые компоненты находятся в одном пакете, а производные компоненты — в другом, вам нужно, чтобы документация отражала реквизиты расширенных компонентов в открытых.

Допустим, у вас есть BaseButton.vue в пакете @scoped/core, который расширяется до IconButton.vue в пакете @scoped/extended, реквизиты BaseButton.vue не будут документироваться с помощью IconButton.vue. Это может быть то, что вы хотите, или вам может не хватать большого количества реквизитов.

Используйте опцию validExtends, чтобы разрешить анализ расширенных компонентов в других пакетах.

module.exports = {
  // Добавьте следующую функцию в ваш styleguide.config.js
  validExtends (fullFilePath) {
    return (
      /[\\/]@scoped[\\/]core[\\/]/.test(fullFilePath) ||
      !/[\\/]node_modules[\\/]/.test(fullFilePath)
    )
  }
}

# У меня есть несколько компонентов в одной папке, что мне делать?

Если несколько документированных компонентов находятся в одной системе и вы используете файл ReadMe для их документирования, для каждого компонента будет использоваться основной файл readme.

Доступны три решения в зависимости от вкуса и контекста.

# Блок <docs>

Самое простое решение — использовать блок <docs>. Он хорошо работает с подсветкой синтаксиса в Vetur и помогает держать документацию рядом с кодом.

Компромисс: Markdown-файлы удобно читать без рендеринга (например, на GitHub), а Vue-файлы — нет.

# Именованные файлы Readme

Используйте имя компонента и меняйте расширение .vue на .md, чтобы иметь отдельный файл документации для каждого компонента.

Компромисс: GitHub автоматически показывает именно readme-файл. Именованные файлы документации для отдельных компонентов не будут подхватываться автоматически.

# Удаление ненужной документации

Documenting

В тегах компонента можно указать doclet @example. Обычно он используется, чтобы показать, где находится дополнительная документация.

Также можно использовать специальное значение [none]. В этом случае связанный файл примера будет скрыт.

Если для внутренних компонентов указать @example [none], останется только основной readme целевого компонента.

# Как интегрировать Styleguidist в существующий сайт Nuxtjs?

Предполагается, что у вас есть существующий сайт Nuxtjs или вы используете Nuxtjs в качестве среды разработки для своих компонентов библиотеки. Хотя вы также можете побудить пользователей клонировать ваши репозитории и создавать документы, было бы неплохо интегрировать их в существующий сайт Nuxtjs. Это возможно (с некоторыми оговорками).

Сначала определите маршрут, где должна быть документация Styleguidist. Например, www.mysite.com/docs. Если бы это была обычная страница Nuxt, это был бы файл pages/docs.vue. Поэтому в целевом пути нельзя иметь страницу pages/<dest>.vue.

Далее настройте параметры генерации в nuxt.config.js. Если вы делаете deployment на GitLab, это может выглядеть так:

// nuxt.config.js
export default {
  // ...
  генерировать: {
    реж: 'публичный'
  }
  // ...
}

Если вы уже генерировали Nuxt-сайт и смотрели результат (например, в каталоге public), то знаете, что каждый pages/<dest>.vue становится подкаталогом. Поэтому путь для Styleguidist не должен совпадать с dest.vue.

Теперь обновите styleguide.config.js, чтобы styleguideDir соответствовал generate.dir из nuxt.config.js. Например, если документация должна быть по пути /docs, а generate.dir = "public", то используйте styleguideDir = "public/docs".

Далее соблюдайте порядок: сначала сгенерируйте Nuxt (npm run generate), затем соберите документацию Styleguidist.

# Как использовать имя компонента в примерах с другим displayName

При использовании displayName компоненты в блоке <docs> должны быть импортированы с их displayName вместо name. Это не идеально, поскольку в ваших примерах не используется настоящее имя компонента.

Способ обойти эту проблему — создать компонент-псевдоним с его оригинальным именем.

Изменить root element следующим образом:

// конфигурация/styleguide.root.js
import Vue from 'vue';

export default previewComponent => {
  возвращаться {
    рендер (createElement) {
      вернуть createElement (previewComponent);
    },
    созданный() {
      // Для каждого глобально зарегистрированного компонента
      // создаем псевдоним, если его имя не соответствует его displayName
      Object.entries(Vue.options.comComponents).forEach(c => {
        const displayName = c[0];
        const component = c[1];
        const { name } = component.extendOptions;

        // Если отображаемое имя отличается от имени, создайте псевдоним компонента
        // Пример: displayName компонента AcAlert — Alert
        // Затем мы создаем AcAlert, псевдоним Alert, который будет использоваться в блоке <docs>.
        if (displayName !== имя) {
          Vue.comComponent(имя, компонент);
        }
      });
    },
}
module.exports = {
  renderRootJsx: path.join(__dirname, 'config/styleguide.root.js')
}

Теперь вы можете использовать <AcAlert /> в <docs>, пока в левом меню отображается Alert.
Пример:

<script>
/**
 * Оповещение @displayName
 */
export default {
  название: «АкАлерт»
}
</script>

<template>
  <div>AcAlert</div>
</template>

<docs>
  # Использование ```js
  <АкАлерт />
  <Оповещение
/></документы>

⚠️ В меню компонентов имя AcAlert может не находиться, если в навигации страница называется Alert.

# Как работает поиск в документации

В этом репозитории поиск на сайте документации работает через vuepress-plugin-fulltext-search. Он отличается от поиска компонентов в самом Styleguidist (по меню/именам компонентов).

Что индексируется:

  • заголовок страницы;
  • заголовки внутри страницы (##, ### и т.д.);
  • текстовое содержимое Markdown-файла (.md), включая обычные абзацы.

Как формируется индекс:

  1. При сборке VuePress рендерит Markdown в HTML.
  2. Плагин извлекает из HTML обычный текст и нормализует его.
  3. Для каждой страницы сохраняются поля заголовка, секций и контента.
  4. Поиск в интерфейсе выполняется по этому индексу, поэтому совпадения находятся не только по названию пункта меню, но и по тексту страницы.

Что важно учитывать:

  • индекс пересобирается при vuepress dev/vuepress build;
  • динамический контент, который появляется только в рантайме браузера, в индекс не попадет;
  • результаты зависят от текста, который реально находится в Markdown.

Где настраивается:

  • подключение плагина: docs/.vuepress/config.js (plugins: ['fulltext-search']);
  • зависимость плагина: package.json (vuepress-plugin-fulltext-search).