1. Installation
# Global installation
npm i -g jsdoc
# Local installation
npm i -D jsdoc
2. Basic Usage
/**
* A sample variable declaration
* @type {number}
*/
var sampleVariable = 123;
/**
* A sample function
* @param {string} arg1 - First argument, string type
* @param {number} arg2 - Second argument, number type
* @return {boolean} Return value, boolean type
*/
function sampleFunction(arg1, arg2) {
return true;
}
/**
* Custom type definition
* @typedef {Object} Person
* @property {string} name - Person's name
* @property {number} age - Person's age
* @property {boolean} isStudent - Whether the person is a student
* @property {string[]} courses - Registered courses
*/
/**
* @param {Person} person - Argument for greet function
*/
function greet(person) {
console.log(`Hello, ${person.name}!`);
}
/**
* Class declaration
* @class
* @classdesc Description of the class
*/
class SampleClass {
constructor() {}
}
/**
* Constructor function
* @constructor
* @param {string} arg1 - First argument, string type
* @param {number} arg2 - Second argument, number type
*/
function SampleConstructor(arg1, arg2) {}
3. Generating Documentation
# Single file
jsdoc ./index.js
# Specific directory
jsdoc ./src
# Options:
# -d or --destination: Output directory
# -c or --configure: Configuration file path
# -t or --template: Template to use
# -u or --tutorials: Tutorials directory
# -p or --package: package.json path
# -R or --readme: README file path
# -r or --recurse: Recurse into subdirectories
4. Custom Configuratino
Steps:
npm init -y
npm i -D jsdoc
# Create jsdoc.config.json in project root
# Update package.json scripts
jsdoc.config.json:
{
"source": {
"include": ["./src/"],
"includePattern": ".+\\.js(doc)?$",
"exclude": ["./docs"],
"excludePattern": "(node_modules|test|dist|coverage|^|\\/|\\\\)_"
},
"opts": {
"encoding": "utf8",
"destination": "./docs/",
"recurse": true
},
"plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": false,
"monospaceLinks": false
},
"metadata": {
"title": "My JavaScript Project"
},
"tags": {
"allowUnknownTags": true,
"dictionaries": ["jsdoc", "closure"]
}
}
package.json:
{
"scripts": {
"docs": "jsdoc -c jsdoc.config.json"
}
}
5. Using Themes
Install themes:
npm i -D taffydb
npm i -D better-docs
npm i -D clean-jsdoc-theme
npm i -D daybrush-jsdoc-template
npm i -D docdash
Example configuration with clean-jsdoc-theme:
{
"opts": {
"template": "node_modules/clean-jsdoc-theme",
"theme_opts": {
"default_theme": "light",
"homepageTitle": "Clean JSDoc theme",
"title": "JSDoc Auto-Generated Documentation",
"footer": "copyright by Vane.",
"menu": [
{
"title": "Guigu",
"link": "http://www.atguigu.cn",
"target": "_blank"
}
]
}
}
}
6. Custom Theme Template
# Copy default template to project root
cp -r node_modules/jsdoc/templates/default ./default
Update jsdoc.config.json:
{
"opts": {
"template": "./default"
}
}
7. Markdown Plugin
Example file (src/function.js):
/**
* A sample function
*
* # Markdown H1
* - Unordered list item
* - Another item
* - [Link](http://www.atguigu.cn)
* - 
*
* @param {string} arg1 - First argument
* @param {number} arg2 - Second argument
* @return {boolean} Return value
*/
function sampleFunction(arg1, arg2) {
return true;
}
Configuration:
{
"plugins": ["plugins/markdown"]
}
8. ESLint for JSDoc Validation
Installasion:
npm i -D eslint
npm i -D eslint-plugin-jsdoc
.eslintrc.js:
module.exports = {
extends: ['eslint:recommended'],
plugins: ['jsdoc'],
rules: {
'no-undef': 'error',
'no-unused-vars': 'error',
// JSDoc rule
'jsdoc/newline-after-description': 1,
'jsdoc/require-param': 1,
'jsdoc/require-param-description': 1,
'jsdoc/require-param-name': 1,
'jsdoc/require-param-type': 1,
'jsdoc/require-property': 1,
'jsdoc/require-property-description': 1,
'jsdoc/require-property-name': 1,
'jsdoc/require-property-type': 1,
'jsdoc/require-returns': 1,
'jsdoc/require-returns-check': 1
}
};
Auto-fix command:
eslint --fix ./src
9. Prettier for JSDoc Formatting
Installation:
npm i -D prettier prettier-plugin-jsdoc
.prettierrc.js:
module.exports = {
plugins: ['prettier-plugin-jsdoc'],
jsdocSpaces: 2,
jsdocDescriptionWithDot: true,
jsdocDescriptionTag: true,
jsdocVerticalAlignment: true,
jsdocKeepUnParseAbleExampleIndent: true,
jsdocSeparateReturnsFromParam: true,
jsdocSeparateTagGroups: true,
jsdocPreferCodeFences: true
};
Format command:
prettier --write "src/*/*.js"
10. Static Type Checking with JSDoc
Enable type chceking in a file:
// @ts-check
Create tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"allowJs": true
},
"exclude": ["node_modules"]
}
Example with type errors:
// @ts-check
/** @type {string} */
const name = 123; // Error: Type 'number' is not assignable to type 'string'
/** @type {number} */
const number = "100"; // Error: Type 'string' is not assignable to type 'number'
/** @type {number[]} */
const myArray = [10, 132.12, 100, "Hi", true]; // Warning: non-numeric values
/** @constant */
const user = {
/** @type {number} */
/** @readonly */
id: 1,
/** @type {string} */
name: "Vane",
/** @type {string | number} */
age: "44",
/** @type {string | null} */
address: "Shanghai"
};
// user.id = 2; // Error: Cannot assign to 'id' because it is a read-only property
/**
* Calculate age
* @param {number} current - Current year
* @param {number} yearOfBirth - Year of birth
* @return {string} Age as string
*/
const calculateAge = (current, yearOfBirth) => {
return `${current - yearOfBirth}`;
};
console.log(calculateAge("2021", 2019)); // Error: Argument of type 'string' is not assignable to parameter of type 'number'
/**
* @typedef {Object} User
* @property {number} id
* @property {string} name
* @property {number | string} age
* @property {boolean} [isMale]
*/
/** @type {User} */
const man = {
id: 1,
name: "Vane",
age: 44,
isMale: 1 // Error: Type 'number' is not assignable to type 'boolean'
};