ESLint valid-jsdoc 规则完全指南:JSDoc 注释校验逻辑、全部配置选项与 v9.0.0 移除迁移方案
【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint
valid-jsdoc是 ESLint 内置的"suggestion"类规则,用于校验 JavaScript 代码中 JSDoc 注释的有效性(格式正确)与一致性(与函数定义同步),例如参数名是否匹配、返回值类型与描述是否齐全。本文基于当前仓库中该规则的完整文档(docs/src/rules/valid-jsdoc.md)展开,并结合仓库内的规则元数据与 v9.0.0 迁移指南,系统讲解 JSDoc 的基础写法、该规则校验的六类问题、全部 8 个配置选项及示例,以及该规则在 ESLint v9.0.0 中被移除后的替代与迁移方案,读完后你将能够准确配置并理解这套 JSDoc 质量约束体系。
规则概况:类型、相关规则与版本轨迹
从文档 frontmatter 元数据可以确认该规则的基础信息:
- 规则类型(rule_type):
suggestion,即它用于提示代码风格与文档质量方面的改进建议,而非运行时错误或易错点排查。 - 相关规则(related_rules):require-jsdoc,两者是配套关系——
require-jsdoc负责"强制要求写 JSDoc 注释",valid-jsdoc负责"校验已写注释的质量"。 - 重要声明:该规则已在ESLint v9.0.0 中被移除,官方文档明确说明由第三方插件
eslint-plugin-jsdoc的等价规则替代。
仓库中的元数据文件进一步印证了这一版本轨迹:
- conf/rule-type-list.json 中将
valid-jsdoc标记为{ "removed": "valid-jsdoc", "replacedBy": [] },即已移除且没有内置规则接替。 - docs/src/_data/rule_versions.json 记录了该规则的完整生命周期:v0.4.0 加入(见
added段),v9.0.0-alpha.0 移除(见removed段)。 - 从当前仓库 lib/rules 目录的规则实现列表中已经找不到
valid-jsdoc.js与require-jsdoc.js,这与文档声明的移除状态完全一致。
使用提示:如果你正在使用 ESLint v8 或更早版本,本文的配置与示例可直接套用;如果你已经升级到 v9.0.0 及以上,请直接阅读文末的"迁移方案"章节。
什么是 JSDoc:先从一段标准注释说起
JSDoc 是一种从 JavaScript 代码中带格式的注释自动生成 API 文档的工具。一个典型的函数 JSDoc 注释如下:
/** * Add two numbers. * @param {number} num1 The first number. * @param {number} num2 The second number. * @returns {number} The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; }JSDoc 注释的价值取决于它的正确性与一致性:
- 如果注释因为拼写错误而格式不合法,那么基于它生成的文档就会不完整;
- 如果注释在函数定义被修改后没有同步更新,那么前后不一致的注释会误导阅读代码的人。
valid-jsdoc规则正是针对这两类问题设计的——它不做"是否写了注释"的强制(那是require-jsdoc的职责),而是专注于"写了的注释是否正确、是否与代码同步"。
Rule Details:该规则会报告哪些问题
valid-jsdoc会检查函数、方法及构造函数上的 JSDoc 注释,并报告以下任一问题:
- 缺少参数标签:注释中没有
@arg、@argument或@param标签; - 参数名顺序不一致:注释中的参数名顺序与函数/方法的实际形参顺序不一致;
- 缺少返回标签:注释中没有
@return或@returns标签; - 缺少参数或返回类型:
@param/@returns标签缺少{类型}声明; - 缺少参数或返回描述:
@param/@returns标签缺少描述文字; - 语法错误:注释本身存在语法问题(如
{}大括号未闭合)。
同时需要明确该规则的两个边界:
- 它不报告"类、函数或方法缺少 JSDoc 注释"——这是 require-jsdoc 的职责范围;
- 它不支持 Google Closure 文档工具的全部使用场景。例如
(/**number*/ n => n * 2);这种写法会被标记为"缺少合适的函数 JSDoc 注释",尽管/**number*/本意是类型提示(type hint)而非函数文档块。如果你习惯用这种方式书写类型提示,官方文档明确不建议使用本规则。
错误示例(默认选项下)
以下代码在默认配置(/*eslint valid-jsdoc: "error"*/)下都会触发报错:
/*eslint valid-jsdoc: "error"*/ // expected @param tag for parameter num1 but found num instead // missing @param tag for parameter num2 // missing return type /** * Add two numbers. * @param {number} num The first number. * @returns The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; } // missing brace // missing @returns tag /** * @param {string name Whom to greet. */ function greet(name) { console.log("Hello " + name); } // missing parameter type for num1 // missing parameter description for num2 /** * Represents a sum. * @constructor * @param num1 The first number. * @param {number} num2 */ function sum(num1, num2) { this.num1 = num1; this.num2 = num2; }逐一解读这三段错误示例所覆盖的校验点:
add函数:@param {number} num与形参num1名字不一致(期望找到num1却找到num);缺少参数num2的@param标签;@returns缺少类型。greet函数:@param {string name Whom to greet.中花括号未闭合,属于语法错误;同时完全没有@returns标签。sum构造函数:@param num1缺少参数类型;@param {number} num2缺少参数描述。
正确示例(默认选项下)
以下写法在默认选项下全部通过校验:
/*eslint valid-jsdoc: "error"*/ /** * Add two numbers. * @param {number} num1 The first number. * @param {number} num2 The second number. * @returns {number} The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; } // default options allow missing function description // return type `void` means the function has no `return` statement /** * @param {string} name Whom to greet. * @returns {void} */ function greet(name) { console.log("Hello " + name); } // @constructor tag allows missing @returns tag /** * Represents a sum. * @constructor * @param {number} num1 The first number. * @param {number} num2 The second number. */ function sum(num1, num2) { this.num1 = num1; this.num2 = num2; } // class constructor allows missing @returns tag /** * Represents a sum. */ class Sum { /** * @param {number} num1 The first number. * @param {number} num2 The second number. */ constructor(num1, num2) { this.num1 = num1; this.num2 = num2; } } // @abstract tag allows @returns tag without `return` statement class Widget { /** * When the state changes, does it affect the rendered appearance? * @abstract * @param {Object} state The new state of the widget. * @returns {boolean} Is current appearance inconsistent with new state? */ mustRender (state) { throw new Error("Widget subclass did not implement mustRender"); } } // @override tag allows missing @param and @returns tags class WonderfulWidget extends Widget { /** * @override */ mustRender (state) { return state !== this.state; // shallow comparison } }这些正确示例揭示了几个重要的默认行为规则:
- 函数描述(description)默认可不写——默认选项不要求每个注释都有函数说明文字;
- 返回类型
void表示函数没有return语句——greet函数没有返回值,用@returns {void}声明即可通过; @constructor标签允许省略@returns标签——构造函数不需要返回值标签;- 类构造函数(class constructor)同样允许省略
@returns标签; @abstract标签允许在无return语句的方法上保留@returns标签(抽象方法往往抛出异常而非返回);@override标签允许省略@param和@returns标签——覆盖实现直接继承父类的文档约定。
Options:全部配置选项详解
该规则接受一个对象选项,核心可配置项共 8 个:
| 选项 | 作用 | 默认行为 |
|---|---|---|
prefer | 指定标签别名偏好,如"return": "returns"表示用@returns代替@return | 不强制统一(即文档未设置默认别名表) |
preferType | 指定类型字符串的写法偏好,如"object": "Object"表示用Object代替object | 不强制统一 |
requireReturn | 是否要求@returns标签(详见下文) | true |
requireReturnType | 置为false时允许返回标签缺少类型 | 要求返回标签必须有类型 |
matchDescription | 用正则字符串约束每个 JSDoc 注释的描述,如".+"强制必须有描述 | 不约束描述 |
requireParamDescription | 置为false时允许参数标签缺少描述 | 要求参数标签必须有描述 |
requireReturnDescription | 置为false时允许返回标签缺少描述 | 要求返回标签必须有描述 |
requireParamType | 置为false时允许参数标签缺少类型 | 要求参数标签必须有类型 |
说明:上表中"默认行为"一列,
requireReturn的默认值true是文档明确声明的;其余选项文档以"false允许缺失"的表述给出,可以推断其默认语义为"要求齐全"。prefer、preferType、matchDescription未设置时表示不施加对应约束。
其中requireReturn的语义较为特殊,值得单独展开:
true(默认值):即使函数或方法没有return语句也要求@returns标签(注意:此取值不适用于构造函数,构造函数仍允许省略);false:当且仅当函数或方法含有return语句、或确实返回了值(例如async函数)时,才要求@returns标签(此取值适用于构造函数)。
prefer:统一标签别名
示例配置:"prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" },含义是:遇到@arg/@argument应用@param,遇到@class应用@constructor,遇到@return应用@returns,遇到@virtual应用@abstract。
以下代码在prefer配置下均被判定为错误:
/*eslint valid-jsdoc: ["error", { "prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" } }]*/ /** * Add two numbers. * @arg {number} num1 The first number. * @arg {number} num2 The second number. * @return {number} The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; } /** * Represents a sum. * @class * @argument {number} num1 The first number. * @argument {number} num2 The second number. */ function sum(num1, num2) { this.num1 = num1; this.num2 = num2; } class Widget { /** * When the state changes, does it affect the rendered appearance? * @virtual * @argument {Object} state The new state of the widget. * @return {boolean} Is current appearance inconsistent with new state? */ mustRender (state) { throw new Error("Widget subclass did not implement mustRender"); } }即@arg、@class、@return、@virtual、@argument等别名标签会被统一纠正为prefer中指定的首选标签。
preferType:统一类型写法
示例配置:"preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" },含义是:类型声明中应使用小写boolean/number/string和首字母大写的Object。
以下代码在preferType配置下均被判定为错误:
/*eslint valid-jsdoc: ["error", { "preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" } }]*/ /** * Add two numbers. * @param {Number} num1 The first number. * @param {Number} num2 The second number. * @returns {Number} The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; } /** * Output a greeting as a side effect. * @param {String} name Whom to greet. * @returns {void} */ function greet(name) { console.log("Hello " + name); } class Widget { /** * When the state changes, does it affect the rendered appearance? * @abstract * @param {object} state The new state of the widget. * @returns {Boolean} Is current appearance inconsistent with new state? */ mustRender (state) { throw new Error("Widget subclass did not implement mustRender"); } }可以看到,{Number}、{String}、{object}、{Boolean}都会被报告,需要替换为配置中约定的类型写法。
requireReturn:控制返回标签的必需性
当配置"requireReturn": false时,@returns标签只应在函数确实返回值的场景出现。以下代码被判定为错误:
/*eslint valid-jsdoc: ["error", { "requireReturn": false }]*/ // unexpected @returns tag because function has no `return` statement /** * @param {string} name Whom to greet. * @returns {string} The greeting. */ function greet(name) { console.log("Hello " + name); } // add @abstract tag to allow @returns tag without `return` statement class Widget { /** * When the state changes, does it affect the rendered appearance? * @param {Object} state The new state of the widget. * @returns {boolean} Is current appearance inconsistent with new state? */ mustRender (state) { throw new Error("Widget subclass did not implement mustRender"); } }第一个例子中greet函数体没有return语句,却写了@returns标签,属于"多余的返回标签";第二个例子中mustRender抛异常而非返回,需要补充@abstract标签(如上文正确示例所示)才能保留@returns。
以下代码在"requireReturn": false下是正确的:
/*eslint valid-jsdoc: ["error", { "requireReturn": false }]*/ /** * @param {string} name Whom to greet. */ function greet(name) { console.log("Hello " + name); }即无返回值的函数直接省略@returns标签即可。
requireReturnType:允许返回标签缺类型
配置"requireReturnType": false后,@returns可以不带{类型}:
/*eslint valid-jsdoc: ["error", { "requireReturnType": false }]*/ /** * Add two numbers. * @param {number} num1 The first number. * @param {number} num2 The second number. * @returns The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; }requireParamType:允许参数标签缺类型
配置"requireParamType": false后,@param可以不带{类型}:
/*eslint valid-jsdoc: ["error", { "requireParamType": false }]*/ /** * Add two numbers. * @param num1 The first number. * @param num2 The second number. * @returns {number} The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; }matchDescription:约束注释描述内容
matchDescription接受一个正则字符串,用于匹配每个 JSDoc 注释的描述部分(不作用于参数或返回标签内部的描述)。例如".+"要求注释必须包含描述文字:
/*eslint valid-jsdoc: ["error", { "matchDescription": ".+" }]*/ // missing function description /** * @param {string} name Whom to greet. * @returns {void} */ function greet(name) { console.log("Hello " + name); }上面的注释没有任何函数描述,因此在matchDescription: ".+"下报"缺少函数描述"。
requireParamDescription:允许参数标签缺描述
配置"requireParamDescription": false后,@param可以只写类型不写描述:
/*eslint valid-jsdoc: ["error", { "requireParamDescription": false }]*/ /** * Add two numbers. * @param {number} num1 * @param {number} num2 * @returns {number} The sum of the two numbers. */ function add(num1, num2) { return num1 + num2; }requireReturnDescription:允许返回标签缺描述
配置"requireReturnDescription": false后,@returns可以只写类型不写描述:
/*eslint valid-jsdoc: ["error", { "requireReturnDescription": false }]*/ /** * Add two numbers. * @param {number} num1 The first number. * @param {number} num2 The second number. * @returns {number} */ function add(num1, num2) { return num1 + num2; }组合配置实战:一份可落地的完整配置
将上述选项组合起来,可以在 eslint.config.js 或.eslintrc中一次性约束 JSDoc 注释的完整质量。以下是一份参考配置(基于文档中各选项的语义组合而成):
{ "rules": { "valid-jsdoc": ["error", { "prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" }, "preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" }, "requireReturn": true, "requireReturnType": true, "requireParamDescription": true, "requireReturnDescription": true, "requireParamType": true, "matchDescription": ".+" }] } }与 require-jsdoc 的协作关系
valid-jsdoc只校验"已存在注释"的质量,不强制"必须写注释"。若团队风格要求所有函数都必须有 JSDoc 文档,则需要搭配 require-jsdoc 一起使用。后者支持对FunctionDeclaration、ClassDeclaration、MethodDefinition、ArrowFunctionExpression、FunctionExpression等节点类型分别配置是否强制要求 JSDoc 注释。两者结合后,才能形成"先强制书写、再校验质量"的完整链路。
When Not To Use It:何时应关闭本规则
如果你完全不使用 JSDoc,那么可以放心关闭本规则。官方文档给出的判断很简单:规则的价值完全建立在"团队以 JSDoc 注释作为 API 文档与代码意图说明"的前提之上;没有这个前提,强行开启只会带来噪音。
迁移方案:ESLint v9.0.0 移除后的替代路径
这是使用本规则必须了解的前置事实。根据文档的重要提示以及仓库中的 v9.0.0 迁移指南(对应章节 "Removedrequire-jsdocandvalid-jsdocrules"):
require-jsdoc与valid-jsdoc两条规则在2018 年即被标记为弃用(deprecated),并在ESLint v9.0.0 正式移除;- 移除后,等价能力由第三方插件
eslint-plugin-jsdoc提供; - 迁移指南提供了现成的 codemod(
@eslint/v8-to-v9-config):当配置中存在这两条已弃用规则时,它会自动删除require-jsdoc/valid-jsdoc、添加eslint-plugin-jsdoc并配置jsdoc({ config: 'flat/recommended' }),同时移除文件中用于引用旧规则的 JSDoc 格式 ESLint 注释。
仓库中关于规则弃用元数据的约定(参见 docs/src/extend/rule-deprecation.md)也印证了这一流程:规则的弃用信息包含弃用起始版本(deprecatedSince)与计划移除版本,移除时在规则清单中以removed状态标记。你可以在 conf/rule-type-list.json 中查看到valid-jsdoc的removed状态,并在 docs/src/_data/rule_versions.json 中查到其加入版本(0.4.0)与移除版本(9.0.0-alpha.0)的完整记录。
结论:若你仍在使用 ESLint v8 及更早版本,valid-jsdoc的上述全部配置与示例可直接使用;若你已升级到 v9.0.0 及以上,请安装eslint-plugin-jsdoc并使用其jsdoc/recommended(flat 格式)或对应规则替代本文所讲的配置,以继续获得 JSDoc 注释有效性校验能力。
【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考