Dokka для Kotlin: полное руководство с примерами
1. Что это и зачем нужна
Dokka — это современный движок генерации документации для языка Kotlin, разработанный компанией JetBrains. В отличие от традиционного JavaDoc, Dokka понимает специфику Kotlin: null-безопасность, функции-расширения, свойства, корутины, sealed-классы и другие уникальные конструкции языка. Если вы пишете библиотеку или API на Kotlin, Dokka позволяет автоматически создать читаемую, структурированную документацию в форматах HTML, Markdown, Javadoc или даже в виде JSON для дальнейшей обработки.
Зачем она нужна? Во-первых, Dokka значительно упрощает поддержку документации в больших проектах — достаточно написать KDoc-комментарии (аналог JavaDoc, но с поддержкой Markdown) в коде, и утилита сгенерирует готовый сайт. Во-вторых, Dokka умеет объединять документацию из нескольких модулей Gradle или Maven в единый проект, что критично для многомодульных библиотек. В-третьих, она поддерживает кастомизацию через шаблоны и плагины, позволяя адаптировать внешний вид под корпоративный стиль.
Dokka активно используется в официальной документации Kotlin (kotlinlang.org), в библиотеках Ktor, Exposed, Kotlinx.serialization и многих других. Она является стандартом де-факто для документирования Kotlin-проектов, и если вы хотите, чтобы ваша библиотека выглядела профессионально — Dokka обязательна к изучению.
2. Установка
Dokka распространяется как плагин для систем сборки Gradle и Maven. Отдельной команды pip или npm не существует, так как это инструмент для JVM-экосистемы. Ниже приведены точные инструкции для Gradle (Kotlin DSL) — самый популярный способ.
Gradle (Kotlin DSL) — плагин для одного модуля
Добавьте в build.gradle.kts:
plugins {
id("org.jetbrains.dokka") version "1.9.20"
}
dependencies {
// Ваши зависимости
}
// Базовая конфигурация (опционально)
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask>() {
outputDirectory.set(file("$buildDir/dokka"))
}
Gradle (Groovy DSL)
plugins {
id "org.jetbrains.dokka" version "1.9.20"
}
Maven
<plugin>
<groupId>org.jetbrains.dokka</groupId>
<artifactId>dokka-maven-plugin</artifactId>
<version>1.9.20</version>
<executions>
<execution>
<phase>pre-site</phase>
<goals>
<goal>dokka</goal>
</goals>
</execution>
</executions>
</plugin>
После настройки запустите команду:
./gradlew dokkaHtml # для HTML
./gradlew dokkaGfm # для Markdown (GFM)
./gradlew dokkaJavadoc # для Javadoc-стиля
3. Быстрый старт — минимальный рабочий пример
Создайте простой Kotlin-файл с KDoc-комментариями:
// src/main/kotlin/com/example/Calculator.kt
package com.example
/**
* Простой калькулятор, демонстрирующий работу Dokka.
*
* @author PythonLib Team
* @since 1.0.0
*/
class Calculator {
/**
* Складывает два числа.
*
* @param a первое слагаемое
* @param b второе слагаемое
* @return сумма a и b
*/
fun add(a: Int, b: Int): Int = a + b
/**
* Делит одно число на другое.
*
* @param a делимое
* @param b делитель (не может быть нулём)
* @return результат деления
* @throws IllegalArgumentException если b == 0
*/
fun divide(a: Double, b: Double): Double {
require(b != 0.0) { "Делитель не может быть нулём" }
return a / b
}
}
Запустите ./gradlew dokkaHtml. В папке build/dokka появится HTML-документация. Откройте index.html — вы увидите страницу с описанием класса Calculator и его методов, включая параметры, возвращаемые значения и исключения.
4. Основные методы/функции/классы
Dokka предоставляет несколько ключевых API для программной генерации документации (через Gradle/Maven) и для кастомизации. Ниже приведены 8 наиболее важных элементов.
4.1. DokkaTask — основная задача Gradle
Сигнатура: class DokkaTask : DefaultTask
Что делает: Это главная задача плагина. Она собирает исходники, парсит KDoc и генерирует документацию в указанном формате.
// build.gradle.kts
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask>() {
outputDirectory.set(file("$buildDir/custom-docs"))
dokkaSourceSets {
named("main") {
includes.from("README.md") // добавить README в документацию
sourceLink {
localDirectory.set(file("src/main/kotlin"))
remoteUrl.set(uri("https://github.com/example/repo/tree/main/src/main/kotlin"))
remoteLineSuffix.set("#L")
}
}
}
}
4.2. DokkaConfiguration — конфигурация сборки
Сигнатура: data class DokkaConfiguration(...)
Что делает: Позволяет программно настроить все параметры генерации: исходники, модули, плагины, формат вывода.
// Пример программной конфигурации (Kotlin Script)
val config = DokkaConfiguration(
moduleName = "MyLib",
outputDir = file("docs"),
format = DokkaConfiguration.OutputFormat.HTML,
sourceSets = listOf(
DokkaSourceSet(
displayName = "main",
sourceRoots = listOf(file("src/main/kotlin"))
)
)
)
4.3. DokkaGenerator — движок генерации (низкоуровневый API)
Сигнатура: class DokkaGenerator(config: DokkaConfiguration, context: DokkaContext)
Что делает: Запускает процесс генерации из кода. Полезно для интеграции в собственные инструменты.
import org.jetbrains.dokka.DokkaGenerator
import org.jetbrains.dokka.DokkaConfiguration
fun generateDocs() {
val config = DokkaConfiguration(
moduleName = "MyModule",
outputDir = file("docs"),
format = DokkaConfiguration.OutputFormat.HTML
)
val generator = DokkaGenerator(config, DokkaContext())
generator.generate()
}
4.4. DokkaPlugin — базовый класс для плагинов
Сигнатура: abstract class DokkaPlugin
Что делает: Позволяет расширять функциональность Dokka: добавлять кастомные шаблоны, трансформации, фильтры.
class CustomPlugin : DokkaPlugin() {
val customTransformer by extending {
// Добавляет кастомный трансформер для HTML
transform { content -> content.replace("TODO", "FIXME") }
}
}
4.5. Documentable — модель данных документации
Сигнатура: sealed class Documentable
Что делает: Представляет элемент документации: класс, функцию, свойство. Используется для кастомной обработки.
// Пример получения всех функций из документации
fun processDocumentables(docs: List<Documentable>) {
docs.filterIsInstance<DFunction>().forEach { function ->
println("Функция: ${function.name}, параметры: ${function.parameters}")
}
}
4.6. DokkaConsoleLogger — логирование
Сигнатура: class DokkaConsoleLogger : DokkaLogger
Что делает: Выводит сообщения о процессе генерации в консоль. Полезно для отладки.
val logger = DokkaConsoleLogger()
logger.info("Начинаем генерацию документации")
logger.warn("Обнаружены недокументированные функции")
logger.error("Ошибка парсинга файла Main.kt")
4.7. DokkaSourceSet — конфигурация набора исходников
Сигнатура: data class DokkaSourceSet(...)
Что делает: Определяет один модуль или набор исходных файлов для документирования.
val sourceSet = DokkaSourceSet(
displayName = "Core API",
sourceRoots = listOf(file("src/main/kotlin/core")),
classpath = listOf(file("libs/some.jar")),
includes = listOf(file("docs/overview.md"))
)
4.8. DokkaOutputFormat — формат вывода
Сигнатура: enum class DokkaOutputFormat
Что делает: Определяет формат генерируемой документации: HTML, Markdown (GFM), Javadoc, JSON.
// Выбор формата в конфигурации
val config = DokkaConfiguration(
format = DokkaConfiguration.OutputFormat.HTML // или GF_MARKDOWN, JAVADOC, JSON
)
// Проверка формата
when (config.format) {
DokkaConfiguration.OutputFormat.HTML -> println("Генерируем HTML")
DokkaConfiguration.OutputFormat.JSON -> println("Генерируем JSON для CI")
}
5. Реальный практический пример (150+ строк кода)
Создадим полноценный проект библиотеки для работы с математическими векторами, с KDoc-комментариями и генерацией документации через Dokka.
Структура проекта:
vector-lib/
├── build.gradle.kts
├── settings.gradle.kts
├── src/
│ └── main/
│ └── kotlin/
│ └── com/
│ └── pythonlib/
│ └── vector/
│ ├── Vector2D.kt
│ ├── Vector3D.kt
│ └── VectorMath.kt
└── docs/
└── overview.md
build.gradle.kts
plugins {
kotlin("jvm") version "1.9.22"
id("org.jetbrains.dokka") version "1.9.20"
}
group = "com.pythonlib"
version = "1.0.0"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test"))
}
tasks.dokkaHtml {
outputDirectory.set(file("$buildDir/dokka-html"))
dokkaSourceSets {
named("main") {
includes.from("docs/overview.md")
sourceLink {
localDirectory.set(file("src/main/kotlin"))
remoteUrl.set(uri("https://github.com/pythonlib/vector-lib/tree/main/src/main/kotlin"))
remoteLineSuffix.set("#L")
}
}
}
}
Vector2D.kt
package com.pythonlib.vector
/**
* Двумерный вектор с базовыми операциями.
*
* @property x координата X
* @property y координата Y
* @constructor Создаёт вектор с заданными координатами
*/
data class Vector2D(val x: Double, val y: Double) {
/**
* Вычисляет длину (модуль) вектора.
*
* @return длина вектора, всегда неотрицательна
*/
fun magnitude(): Double = kotlin.math.sqrt(x * x + y * y)
/**
* Нормализует вектор (приводит к единичной длине).
*
* @return новый вектор с длиной 1
* @throws IllegalStateException если вектор нулевой
*/
fun normalize(): Vector2D {
val mag = magnitude()
require(mag > 0.0) { "Нельзя нормализовать нулевой вектор" }
return Vector2D(x / mag, y / mag)
}
/**
* Скалярное произведение с другим вектором.
*
* @param other другой вектор
* @return скалярное произведение (x1*x2 + y1*y2)
*/
infix fun dot(other: Vector2D): Double = x * other.x + y * other.y
/**
* Оператор сложения векторов.
*/
operator fun plus(other: Vector2D) = Vector2D(x + other.x, y + other.y)
/**
* Оператор умножения на скаляр.
*/
operator fun times(scalar: Double) = Vector2D(x * scalar, y * scalar)
}
Vector3D.kt
package com.pythonlib.vector
/**
* Трёхмерный вектор с поддержкой векторного произведения.
*
* @property x координата X
* @property y координата Y
* @property z координата Z
*/
data class Vector3D(val x: Double, val y: Double, val z: Double) {
/**
* Вычисляет длину вектора.
*/
fun magnitude(): Double = kotlin.math.sqrt(x * x + y * y + z * z)
/**
* Векторное произведение с другим вектором.
*
* @param other второй вектор
* @return новый вектор, перпендикулярный обоим исходным
*/
infix fun cross(other: Vector3D): Vector3D {
return Vector3D(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
)
}
/**
* Скалярное произведение.
*/
infix fun dot(other: Vector3D): Double = x * other.x + y * other.y + z * other.z
}
VectorMath.kt
Также в библиотеке