Программисты всегда пользовались генераторами документации, когда это было возможно. Это упрощает документирование, позволяет получить справку по продукту без обращения к коду самого проекта. В Программе долгое время использовался JavaDoc, т.к. большинство проектов написаны на Java, но это было до недавнего времени. Сейчас проекты развиваются  - мало кто представляет хороший продукт без хорошего UI. Отрасль frontend дала жизнь новому направлению разработки — разработчик UI. Концентрируясь на удобстве пользователя, а не на бизнес-процессах, UI-разработка позволяет избегать  сложности бизнес-приложений — камень преткновения многих enterprise-решений.

image

У Java разработчиков есть JavaDoc, а что есть у разработчиков UI?


Долгое время в этой сфере не было достойных инструментов, поскольку сложно подвергнуть автоматизации то, что не систематизировано. Со временем, появился инструмент, аналогичный JavaDoc, который даже получил схожее название — JSDoc. К его ключевым недостаткам можно отнести то, что он заставлял писать код определенным образом, что не всегда подходит для конкретного проекта. Стоит отметить, что код раздувался из-за обилия комментариев, что снижало читабельность самого кода для команды разработки.

Все изменилось в UI-разработке с приходом React. Все интерфейсы стали делиться на атомарные кусочки, из которых стали собираться огромные приложения: каждый кусок изолирован и покрыт необходимыми тестами. Каждая компания имеет свою собственную библиотеку UI компонентов, которые среди разработчиков еще называют UIKit.

В программе «Единая фронтальная система» мы разработали свою библиотеку, однако, и ее необходимо было документировать.

Мы начали писать документацию, но быстро пришли к пониманию того, что готовить ее вручную очень трудозатратно. Мы теряем драгоценное время на документировании, при этом отстаём в развитии самого проекта. Родилась идея генерировать документацию прямо из кода, идея не нова, но мы решились попробовать. У нас был проект на React и TypeScript. Используя слабо документированные возможности TypeScript, мы начали делать свою генерацию для каждого компонента. Все комментарии к каждому свойству компонента становились кусочками той документации, которая выводилась.

Как этого удалось достичь?


Мы не стали погружаться глубоко в корни TypeScript — это заняло бы слишком много времени. Использовав typedoc,  получили структуру проекта в виде json, по этой структуре мы зеркально выстраиваем проект, но уже зная описания самих компонентов. Для удобной подгрузки описаний в саму документацию, мы реализовали особый компонент, который из зеркалированной структуры «вытягивает» описание и отображает его на странице. Звучит сложно, но на практике это работает как часы.

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

Мы разместили решение  на крупнейшем портале совместной разработки GitHub, чтобы вы могли использовать наш инструмент в своей ежедневной работе. Будем рады пообщаться в комментариях к посту.

Мы продолжаем работать над усовершенствованием решения, а именно:

  • Созданием live reloading: больше не нужно будет ждать пересборки всей библиотеки, чтобы увидеть результат в документации.

  • Поддержкой JavaScript: мы понимаем, что сейчас многие проекты не используют TypeScript в своих проектах.

  • Обновлением дизайна: сейчас инструмент выглядит аскетично, но это наши первые шаги в open source, обещаем, мы исправимся!
Поделиться с друзьями
-->

Комментарии (12)


  1. staticlab
    03.03.2017 14:24

    Все изменилось в UI-разработке с приходом React. Все интерфейсы стали делиться на атомарные кусочки, из которых стали собираться огромные приложения

    Неужели этого не было, в частности, в компонентах ExtJS или директивах AngularJS?


    1. Luanre
      05.03.2017 16:40

      Было, однако, React ввел хайп на тему компонентов, раньше эта тема никогда так бурно не обсуждалась


  1. raveclassic
    03.03.2017 14:44
    +2

    Демку бы залили куда-нибудь.


    1. Luanre
      03.03.2017 17:20

      Пример пока можно посмотреть в папке examples
      https://github.com/Sberbank-Technology/ufs-react-doc/tree/release/1.0/examples/simple
      Планируем добавить на gh-pages


      1. vintage
        03.03.2017 21:16
        +1

        Напишите, когда добавите. Интересно чем отличается от всяких tsdoc.


        1. Luanre
          05.03.2017 16:52

          Генератор сам по себе основан на typedoc, для себя внутри команды мы начали генерировать документацию изначально с помощью него. Конечно, мы еще не все фишки генератора перетащили на гитхаб, но мы работаем над этим и скоро проект пополнится новыми фишками :)
          Если интересно, можете оставить контакты на NVNadorichev.SBT@sberbank.ru и будем держать в курсе событий


      1. timramone
        04.03.2017 10:20
        +1

        Так и где там пример? Там пара компонентов и всё. Как мне понять, что делает ваш генератор документации, не запуская npm run docs-dev самостоятельно? :)


        1. Luanre
          07.03.2017 00:57

          Временно разместил пример здесь

          Код, по которому был сгенерирован пример
          declare var require: any;
          
          import * as React from 'react';
          const styles = require('./Button.css') as any;
          
          export enum ButtonType {
              Small, Standard, Big
          }
          
          interface Props {
              /** onClick handler */
              onClick?: React.EventHandler<React.MouseEvent<HTMLButtonElement>>;
          
              /** Button type */
              type?: ButtonType;
          }
          
          /** 
           * Simple button
           */
          export default class Button extends React.Component<Props, {}> {
              onClick = (event) => this.props.onClick(event);
          
              render() {
                  let className;
                  const { type } = this.props;
          
                  switch(type) {
                      case ButtonType.Small:
                          className = styles.small;
                          break;
                      case ButtonType.Big:
                          className = styles.big;
                          break;
                      case ButtonType.Standard:
                      default:
                          className = styles.standard;
                  }
          
                  return <button className={className}>{this.props.children}</button>;
              }
          }
          


          1. Opty
            07.03.2017 10:14
            +1

            Вот в ридми это надо первым делом, а то вообще непонятно с ходу — что делает. А так молодцы, лайк!)


          1. timramone
            07.03.2017 22:27

            Спасибо, стало на много лучше.


  1. Chaptykov
    03.03.2017 15:11
    +2

    Да, очень бы хотелось скриншот, демо, сравнение с конкурентами (например, Styleguidist или SourceJS).


  1. rusmeloman
    03.03.2017 22:36

    Поздравляю, молодцы Ребята!