Статьи

Введение в JSDoc

JSDoc является стандартом де-факто для документирования кода JavaScript. Вам нужно знать хотя бы его синтаксис (который также используется многими другими инструментами), если вы публикуете код. Увы, документации по-прежнему мало, но этот пост может помочь — он показывает, как запустить JSDoc и как работает его синтаксис. (JSDoc wiki [2] является основным источником этого поста, некоторые примеры заимствованы из него.)

В качестве инструмента JSDoc берет код JavaScript со специальными комментариями / ** * / и создает для него HTML-документацию. Например: учитывая следующий код.

    /** @namespace */
    var util = {
        /**
         * Repeat <tt>str</tt> several times.
         * @param {string} str The string to repeat.
         * @param {number} [times=1] How many times to repeat the string.
         * @returns {string}
         */
        repeat: function(str, times) {
            if (times === undefined || times < 1) {
                times = 1;
            }
            return new Array(times+1).join(str);
        }
    };

Сгенерированный HTML выглядит следующим образом в веб-браузере:

Этот пост начинается с быстрого начала, поэтому вы можете попробовать JSDoc немедленно, если вы нетерпеливы. После этого предоставляется дополнительная справочная информация.

1. Быстрый старт

Для действий, описанных ниже, вам нужно установить Java. JSDoc включает в себя сценарий оболочки jsrun.sh, для работы которого требуется Unix (включая OS X и Linux). Но должно быть легко перевести этот скрипт в командный файл Windows.

  • Загрузите последнюю версию jsdoc_toolkit . Распакуйте архив, скажем, в $ HOME / jsdoc-toolkit.
  • Сделайте скрипт $ HOME / jsdoc-toolkit / jsrun.sh исполняемым и скажите ему, где искать двоичный файл JSDoc и шаблон (который контролирует, как будет выглядеть результат).
        JSDOCDIR="$HOME/local/jsdoc-toolkit"
        JSDOCTEMPLATEDIR="$JSDOCDIR/templates/jsdoc"
    

    Теперь вы можете переместить скрипт куда угодно, например, в каталог bin /. Для этой демонстрации мы не перемещаем сценарий.

  • Используйте jsrun.sh для каталога файлов JavaScript:
    $HOME/jsdoc-toolkit/jsrun.sh -d=$HOME/doc $HOME/js
    
    • Входные данные: $ HOME / js — каталог файлов JavaScript (см. Пример ниже).
    • Вывод: $ HOME / doc — куда записать сгенерированные файлы.

Если вы поместите код JavaScript в начале этого поста в файл $ HOME / js / util.js, то JSDoc создаст следующие файлы:

    $HOME/doc
    +-- files.html
    +-- index.html
    +-- symbols
        +-- _global_.html
        +-- src
        ¦   +-- util.js.html
        +-- util.html

2. Введение: что такое JSDoc?

Это общая проблема программирования: вы написали код JavaScript, который будет использоваться другими, и вам нужна красивая HTML-документация его API. Java впервые внедрила этот домен с помощью инструмента JavaDoc. Квази-стандартом в мире JavaScript является JSDoc. Как показано выше, вы документируете сущность, помещая перед ней специальный комментарий, который начинается с двух звездочек.

Шаблоны. Чтобы что-то выводить, JSDoc всегда нужен шаблон , смесь JavaScript и специально размеченный HTML, который объясняет, как перевести проанализированную документацию в HTML. JSDoc поставляется со встроенным шаблоном, но есть и другие, которые вы можете скачать [3].

2.1. Терминология и соглашения JSDoc

  • Доклет: JSDoc вызывает свои комментарии doclets, что противоречит терминологии JavaDoc, где такие комментарии называются комментариями документа, а доклет похож на шаблон JSDoc, но написан на Java.
  • Переменная: термин переменная в JSDoc часто относится ко всем документируемым объектам, которые включают в себя глобальные переменные, свойства объекта и внутренние члены.
  • Свойства экземпляра: в JavaScript обычно помещают методы в прототип, чтобы делиться ими со всеми экземплярами класса, в то время как поля (нефункциональные свойства) помещаются в каждый экземпляр. JSDoc объединяет общие свойства и свойства каждого экземпляра и вызывает их свойства экземпляра .
  • Свойства класса, статические свойства: это свойства классов, обычно функций конструктора. Например, Object.create является свойством класса Object.
  • Внутренние члены: внутренний член — это данные, вложенные в функцию. Наиболее важными для документации являются личные данные экземпляра, вложенные в функцию конструктора.
        function MyClass() {
            var privateCounter = 0; // an inner member
            this.inc = function() { // an instance property
                privateCounter++;
            };
        }
    

2.2. Синтаксис

Давайте рассмотрим комментарий, показанный в начале:

    /**
     * Repeat <tt>str</tt> several times.
     * @param {string} str The string to repeat.
     * @param {number} [times=1] How many times to repeat the string.
     * @returns {string}
     */

Это демонстрирует некоторый синтаксис JSDoc, который состоит из следующих частей.

  • Комментарий JSDoc: это блочный комментарий JavaScript, первым символом которого является звездочка. Это создает иллюзию, что токен / ** запускает такой комментарий.
  • Теги: комментарии структурированы по начальным строкам с тегами , ключевым словам с префиксом @. @param — пример выше.
  • HTML: вы можете свободно использовать HTML в комментариях JSDoc; например, <tt> для отображения слова моноширинным шрифтом.
  • Аннотации типов: тип значения можно задокументировать, поместив имя типа в фигурные скобки после соответствующих тегов. Варианты:

    Одиночный тип: @param {string} name
    Несколько типов: @param {string | number} idCode
    Массивы типа: @param {string []} names
  • Пути к именам: используются для ссылки на переменные внутри комментариев JSDoc. Синтаксис таких путей следующий.
        myFunction
        MyConstructor
        MyConstructor.classProperty
        MyConstructor#instanceProperty
        MyConstructor-innerMember
    

2,3. Слово о типах

В JavaScript есть два вида значений: примитивы и объекты [7].

  • Примитивные типы: логическое, число, строка. Значения undefined и null также считаются примитивными.
  • Типы объектов. Все остальные типы являются типами объектов , включая массивы и функции.

Осторожно: имена примитивных типов начинаются со строчной буквы. Каждый примитивный тип имеет соответствующий
тип оболочки, тип объекта с заглавным именем, экземплярами которого являются объекты:

  • Тип оболочки boolean — Boolean.
  • Тип обертки числа — Число.
  • Тип обёртки строки — String.

Получение имени типа значения:

  • Примитивное значение p: через typeof p.
        > typeof ""
        'string'
    

    Сравните: экземпляр типа оболочки является объектом.

        > typeof new String()
        'object'
    
  • Значение объекта o: через o.constructor.name. Пример:
        > new String().constructor.name
        'String'
    

3. Основные теги

Мета-данные:

  • @fileOverview: отмечает комментарий JSDoc, который описывает весь файл.
  • @author: Кто написал задокументированную переменную?
  • @deprecated: указывает, что переменная больше не поддерживается. Рекомендуется задокументировать, что использовать вместо этого.
  • @example: содержит пример кода, иллюстрирующий, как следует использовать данный объект.
    /**
     * @example
     * var str = "abc";
     * console.log(repeat(str, 3)); // abcabcabc
     */
    

Связь:

  • @see: указывает на связанный ресурс.
    /**
     * @see MyClass#myInstanceMethod
     * @see The <a href="http://example.com">Example Project</a>.
     */
    
  • {@link …}: работает как @see, но может использоваться внутри других тегов.
  • @requires resourceDescription : ресурс, в котором нуждается документированный объект. Описание ресурса — это либо путь к имени, либо описание на естественном языке.

Versioning:

  • @version VersionNumber : указывает версию документированной лица. Пример:
        @version 10.3.1
    
  • @since VersionNumber : указует , так какую версию документированной сущность была доступна. Пример:
        @since 10.2.0
    

4. Документирование функций и методов

Для функций и методов можно задокументировать параметры, возвращаемые значения и исключения, которые они могут генерировать.

  • @param { paramType } paramName description : описывает параметр с именем paramName . Тип и описание не являются обязательными. Примеры:
        @param str
        @param str The string to repeat.
        @param {string} str
        @param {string} str The string to repeat.
    

    Расширенные возможности:

    • Необязательный параметр:
          @param {number} [times] The number of times is optional.
      
    • Необязательный параметр со значением по умолчанию:
          @param {number} [times=1] The number of times is optional.
      
  • @returns { returnType } description : описывает возвращаемое значение функции или метода. Тип или описание могут быть опущены.
  • @throws { exceptionType } description : описывает исключение, которое может быть вызвано во время выполнения функции или метода. Тип или описание могут быть опущены.

4.1. Встроенная информация о типе («встроенные комментарии документа»)

Существует два способа предоставления информации о типе для параметров и возвращаемых значений. Во-первых, вы можете добавить аннотацию типа к @param и @returns.

    /**
     * @param {String} name
     * @returns {Object}
     */
    function getPerson(name) {
    }

Во-вторых, вы можете вставить информацию о типе:

    function getPerson(/**String*/ name) /**Object*/ {
    }

5. Документирование переменных и полей

Поля — это свойства с нефункциональными значениями. Поскольку поля экземпляра часто создаются внутри конструктора, вы должны документировать их там.

  • @type { typeName }: какой тип имеет документированная переменная? Пример:
        /** @constructor */
        function Car(make, owner) {
            /** @type {string} */
            this.make = make;
    
            /** @type {Person} */
            this.owner = owner;
        }
        @type {Person}
    

    Этот тег также можно использовать для документирования возвращаемого типа функций, но в этом случае предпочтительным является @returns.

  • @constant: флаг, который указывает, что документированная переменная имеет постоянное значение.
  • @default defaultValue : каково значение переменной по умолчанию? Пример:
        /** @constructor */
        function Page(title) {
            /**
             * @default "Untitled"
             */
             this.title = title || "Untitled";
        }
    
  • @property { propType } propName description : задокументируйте свойство экземпляра в комментарии класса. Пример:
        /**
         * @class
         * @property {string} name The name of the person.
         */
        function Person(name) {
            this.name = name;
        }
    

    Без этого тега свойства экземпляра документируются следующим образом.

        /**
         * @class
         */
        function Person(name) {
            /**
             * The name of the person.
             * @type {string}
             */
            this.name = name;
        }
    

    Какой из этих стилей использовать — дело вкуса. Хотя @property вносит избыточность.

6. Документирование занятий

Встроенные в JavaScript средства для определения классов слабы, поэтому существует много API, которые помогают с этой задачей [5]. Эти API отличаются, часто радикально, поэтому вы должны помочь JSDoc выяснить, что происходит. Существует три основных способа определения класса:

  • Функция конструктора: Вы должны пометить функцию конструктора, иначе она не будет задокументирована как класс. То есть одна только заглавная буква не помечает функцию как конструктор.
        /**
         * @constructor
         */
        function Person(name) {
        }
    

    @class — это синоним @constructor, но он также позволяет вам описать класс — в отличие от функции, устанавливающей экземпляр (пример см. в документации по тегам ниже).

  • Вызов API и литерал объекта: вам нужны два маркера. Во-первых, вам нужно сообщить JSDoc, что данная переменная содержит класс. Во-вторых, вам нужно пометить литерал объекта как определяющий класс. Последнее делается через тег @lends.
        /** @class */
        var Person = makeClass(
            /** @lends Person# */
            {
                say: function(message) {
                    return "This person says: " + message;
                }
            }
        );
    
  • Вызов API и литерал объекта с помощью метода конструктора: если один из методов в литерале объекта выполняет задачу конструктора (настройка данных экземпляра, [8]), необходимо пометить его так, чтобы поля были найдены JSDoc. , Затем документация класса перемещается в этот метод.
        var Person = makeClass(
            /** @lends Person# */
            {
                /**
                 * A class for managing persons.
                 * @constructs
                 */
                initialize: function(name) {
                    this.name = name;
                },
                say: function(message) {
                    return this.name + " says: " + message;
                }
            }
        );
    

Метки:

  • @constructor: помечает функцию как конструктор.
  • @class: помечает переменную как класс или функцию как конструктор. Может использоваться в комментарии конструктора, чтобы отделить описание конструктора (первая строка ниже) от описания класса (вторая строка ниже).
        /**
         * Creates a new instance of class Person.
         * @class Represents a person. 
         */ 
        Person = function() {
        }
    
  • @constructs: помечает метод в литерале объекта как выполняющий обязанности конструктора. То есть настройка данных экземпляра. В таком случае класс должен быть там задокументирован. Работает в паре с @lends.
  • @lends namePath : указывает, к какому классу относится следующий литерал объекта. Есть два способа внести свой вклад.

    • @lends Person # — литерал объекта передает свойства экземпляра Person.
    • @lends Person — литерал объекта добавляет свойства класса Person.

6.1. Наследование, пространство имен

В JavaScript нет простой поддержки подклассов и нет реальных пространств имен [6]. Таким образом, вы должны помочь JSDoc увидеть, что происходит, когда вы используете обходные пути.

  • @extends namePath : указывает, что документированный класс является подклассом другого. Пример:
        /**
         * @constructor
         * @extends Person
         */
        function Programmer(name) {
            Person.call(this, name);
            ...
        }
        // Remaining code for subclassing omitted
    
  • @augments: синоним @extends.
  • @namespace: объекты можно использовать для имитации пространств имен в JavaScript. Этот тег отмечает такие объекты. Пример:
        /** @namespace */
        var util = {
            ...
        };
    

7. Метатеги

Мета-теги — это теги, которые добавляются к нескольким переменным. Вы помещаете их в комментарий, который начинается с «/ ** # @ +». Затем они добавляются ко всем переменным, пока JSDoc не встретит заключительный комментарий «/ ** # @ — * /». Пример:

    /**#@+
     * @private
     * @memberOf Foo
     */

    function baz() {}
    function zop() {}
    function pez() {}

    /**#@-*/

8. Редко используемые теги

  • @ignore: игнорировать переменную. Обратите внимание, что переменные без / ** комментариев игнорируются.
  • @borrows otherNamePath как это. propName : переменная — это просто ссылка на другое место; это задокументировано там. Пример:
        /**
         * @constructor
         * @borrows Remote#transfer as this.send
         */
        function SpecialWriter() {
            this.send = Remote.prototype.transfer;
        }
    
  • @ описание текста : введите описание, такое же, как весь текст перед первым тегом.

Ручная категоризация. Иногда JSDoc неправильно интерпретирует, что такое переменная. Тогда вы можете помочь с помощью одного из следующих тегов:

Тег Пометить переменную как
@function функция
@field нефункциональное значение
@public общедоступный (особенно внутренние переменные)
@частный частный
@inner внутренний и, следовательно, также частный
@static доступны без инстанциирования

Имя и членство:

  • @ name namePath : переопределить проанализированное имя и использовать вместо него указанное имя.
  • @memberOf parentNamePath : документированная переменная является членом указанного объекта.

Не объяснено здесь:
@event , см. [2].

9. Связанное чтение

  1. jsdoc-toolkit — Генератор документации для JavaScript : домашняя страница JSDoc в Google Code. Включает ссылку на загрузку.
  2. JSDoc wiki : официальная документация JSDoc и источник этого поста.
  3. JSDoc wiki — TemplateGallery : список доступных шаблонов JSDoc.
  4. JSDoc wiki — TagReference : удобная шпаргалка для тегов JSDoc.
  5. Облегченные API наследования JavaScript
  6. Модули и пространства имен в JavaScript
  7. Значения JavaScript: не все является объектом
  8. Прототипы как классы — введение в наследование JavaScript

 

С http://www.2ality.com/2011/08/jsdoc-intro.html