Writing Documentation
There are two sources of documentation in this repository:
- Guides - markdown files that are compiled into the manual for the website
- inline code comments and types - from which the API Docs are compiled
Both are previewable by following the instructions in the Docs Viewer
Great documentation requires both guides and docs. We encourage updating any associated guides affected by code changes as you make them, and writing new guides when appropriate.
API Documentation Infra Overview
API Documentation is generated from TSDoc comments in the source code compiled with TypeDoc and transformed for Vitepress using typedoc-plugin-markdown
TSDoc syntax is similar to YUIDoc and JSDoc but there are occassional nuances where it becomes best to know the underlying grammar is TSDoc and parser is TypeDoc.
TypeDoc is configured to follow our public package entrypoints to auto-discover documentation. It documents everything reachable, public or private including properties and methods that have no associated code docs. It uses typescript to understand the source-code and builds documentation from the combination of Type signatures and TSDoc comments.
This is great, but it means that its very easy to leak private APIs into the docs, use /** @internal */
on things that should not be put into the public docs.
While API Documentation lives with the source-code, the code itself plays no-part in the documentation that is generated: everything is compiled from comments alone.
The below guide will walk through best practices for writing doc comments, important nuances and syntaxes to know, as well as how to test and preview the doc comments.
Documentation Syntax
What are Doc Comments
Only **
comments are compiled as potential documentation, e.g.
/**
* This is a potential documentation block
*/
Where as single star comment blocks are not considered documentation
/*
* This is not a potential documentation block
*/
Where to put Doc Comments
Documentation comments should be placed directly above the symbol they are documenting.
/**
* Documents the class
*/
class Foo {
/**
* Documents the method
*/
bar() {}
/**
* Documents the property
*/
bar = '1';
}
/**
* Documents the interface
*/
interface Foo {
/**
* Documents the member
*/
bar: string;
}
/**
* Documents the type
*/
type Foo = {
/**
* Documents the member
*/
bar: string;
}
/**
* Documents the variable
*/
const Foo = '1';
/**
* Documents the function
*/
function foo() {}
Ignored Doc Comments
When compiling the API documentation, comments using the @internal
tag will be ignored:
For example, the below doc comment would be ignored. This is useful for documenting code for fellow developers that shouldn't be exposed to end consumers.
/**
* This is a private utility for updating the state
* of a relationship.
*
* @internal
*/
function somethingInside() {}
Auto Association
TSDoc and TypeDoc will automatically place the documentation for a method inside the class it is on, the class inside the package it is in and at the export path it is exported from. Because it knows our entrypoints and our types, we don't need to tell it much! It already knows when something is an interface vs a class, when it extends something else, or that it implements a specific signature.
This means you no longer need to add redundant tags like @module
@class
@method
@static
and @property
.
Doc Comments can be Markdown
Doc comments can contain most any valid markdown syntax, most markdown-valid html, and can utilize code-highlighting via language prefix on a code block comment.
For instance
/**
* ## Overview
*
* Some details
*
* ### An Example
*
* ```ts
* new Store();
* ```
*
* @public
*/
Additionally, the markdown parser in use by our docs understands documentation groups, and many other features.
This means we can do code examples that toggle between files or formats.
/**
* ::: code-group
*
* ```ts [example.ts]
* export function numberFromStrong(str: string): number {}
* ```
*
* ```js [example.js]
* export function numberFromStrong(str) {}
* ```
*
* :::
*/
Highlighting, focus management and code groups are three features that combine to enable crafting powerful examples in the documentation.
Doc Comments should start every line with a *
While technically doc comments only need to start with /**
, providing a *
for every line with matching indentation ensures correct parsing of all tags and documentation.
Without this, some decorators in code examples may be incorrectly parsed as documentation tags, and some documentation may be unexpectedly truncated.
Good
/**
* ## Overview
*
* Some details
*
* ### An Example
*
* ```ts
* class User extends Model {
* @attr name;
* }
* ```
*
* @public
*/
Bad
/**
## Overview
Some details
### An Example
\```ts
class User extends Model {
@attr name;
}
\```
@public
*/
Documenting Packages and Subpackages
To create an overview for a module path e.g. @warp-drive/core-types
or @warp-drive/core-types/symbol
all that is needed is a doc comment at the top of the file with the tag `@module.
For instance, to write documentation giving an overview of @warp-drive/core-types
we would do the following in packages/core-types/src/index.ts
/**
* This package provides essential types and symbols used
* by all the other WarpDrive/EmberData packages.
*
* @module
*/
Always specify @since
on non-type public APIs
/**
* @since 1.13.0
* @public
*/
Use @hideconstructor
for classes that aren't directly instantiated by users
/**
* @hideconstructor
*/
class SchemaRecord {}
Methods are documented with @method
and attatch to the most recent class the parser has seen.
Don't document types in @param and @return
Because types are parsed from the typescript, @param and @return should be used to give a meaningful description only.
/**
* Adds two numbers
*
* @param a - the first number to add
* @param b - the second number to add
* @return the sum of the two numbers
*/
function add(a: number, b: number): number {}
Documentation Hygeine
Documentation Tests
CAUTION
Ignore this section. Doc tests are deactivated while we migrate to tsdoc and typedoc.
Run pnpm test:docs
This will lint discovered doc comments for common sources of error, as well as validate that no published documentation has been added or removed unexpectedly.
If documentation has been added, an entry for it should be added to tests/docs/fixtures/expected.js
. If documentation has been removed, similarly any entry for it should be removed from tests/docs/fixtures/expected.js
.
If documentation you've added is not being discovered by the test, it is likely that either
- it may have been excluded due to using an ignored doc comment
- it may have been excluded due to not using the right comment syntax
- it may have been included in the list of paths to search for source code documentation in yuidoc.json
Previewing Documentation
For docs.warp-drive.io
From inside the docs-viewer
directory
- start sync for guides with
bun ./src/start-guides-sync.ts
- build/rebuild the API docs with
pnpm typedoc
(rerun as needed) - start the server with
pnpm dev
, visit the site url
For api.emberjs.com
CAUTION
Ignore this section. Ember api docs are incompatible while we migrate to tsdoc and typedoc. Once the migration is nearing completion we will create a transform to restore these docs.
Run bun preview-api-docs
from the project root or the docs-viewer
directory.
This will build and run the (external) api-docs app with the current state of the api docs in the repo.
Changes need to be manually rebuilt with bun rebuild-api-docs
.
See the Docs Viewer README for more info.