简体   繁体   English

如何使用 JSDoc 注释 Express 中间件?

[英]How to annotate Express middlewares with JSDoc?

I'm trying to document an Express middleware, but the build-in validation tool in WebStorm tells me that types are incorrectly assigned in the following JSDoc block:我正在尝试记录 Express 中间件,但 WebStorm 中的内置验证工具告诉我,以下 JSDoc 块中的类型分配不正确:

/**
 * My middleware.
 *
 * @param {Object} req
 * @param {Object} res
 * @param {Function} next
 * @return {Object}
 */
exports.show = function(req, res, next) {
    ...
};

In Express sources, I didn't find any @typedef s to help me.在 Express 源代码中,我没有找到任何@typedef来帮助我。 Also, I want to avoid things like @param {*} .另外,我想避免诸如@param {*}类的东西。

What is the correct way to document Express middleware using JSDoc?使用 JSDoc 记录 Express 中间件的正确方法是什么? Thanks for any help.谢谢你的帮助。

Use DefinitelyTyped使用确定类型

  1. Install express types npm install --save-dev @types/express安装 express 类型npm install --save-dev @types/express
  2. use e.Response as usually @param {e.Response} res通常使用e.Response @param {e.Response} res

More types更多类型

  • in file /node_modules/@types/express/index.d.ts在文件/node_modules/@types/express/index.d.ts
  • for Response it is e.Response because:对于Responsee.Response因为:

... declare namespace e { ... export interface Response extends core.Response { } ...

WebStorm网络风暴

install types via Settings > Languages & Frameworks > Javascript > Libraries > @types/express通过设置 > 语言和框架 > Javascript > 库 > @types/express 安装类型

You can document your middleware with您可以使用以下方法记录您的中间件

const express = require("express");

/**
 * @param {express.Request} req
 * @param {express.Response} res
 * @param {express.NextFunction} next
 */
function (req, res, next) {}

when you have middleware that add attribute to req, you can also add them with当您有向 req 添加属性的中间件时,您还可以添加它们

const express = require("express");

/**
 * @param {express.Request & {specialParam1 : string, specialParam2 : any}} req
 * @param {express.Response} res
 * @param {express.NextFunction} next
 */
function (req, res, next) {}

or event better, create a typedef for each source of new elem added on "req" and use "&" to create a type combining them all.或者事件更好,为“req”上添加的每个新元素源创建一个typedef,并使用“&”创建一个将它们组合在一起的类型。

First, we agree that middleware are functions;首先,我们同意中间件是函数; no special type declaration will generally be warranted.通常不保证特殊类型声明。 Beyond that, middleware tend to be highly decoupled— modular —which means the @module tag is usually applicable (and this has nice consequences when you run jsdoc).除此之外,中间件往往是高度解耦的——模块化——这意味着@module标签通常是适用的(这在你运行 jsdoc 时会产生很好的结果)。

/**
 * Description of my middleware.
 * @module myMiddleware
 * @function
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Express next middleware function
 * @return {undefined}
 */

The return tag is optional depending on your style guide, since middleware don't return a value.返回标记是可选的,具体取决于您的样式指南,因为中间件不返回值。 Finally, contrary to what Nick and mmm claim, the next parameter is a function.最后,与 Nick 和 mmm 声称的相反, next参数是一个函数。

http://expressjs.com/en/guide/using-middleware.html http://expressjs.com/en/guide/using-middleware.html

Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application's request-response cycle.中间件函数是可以访问请求对象 (req)、响应对象 (res) 和应用程序请求-响应循环中的下一个中间件函数的函数。 The next middleware function is commonly denoted by a variable named next. next 中间件函数通常由名为 next 的变量表示。

next isn't a fancy Express-internal concoction; next不是花哨的 Express 内部混合物; Express passes each middleware function the request, the response, and the next middleware function in the stack, like this: Express 向每个中间件函数传递请求、响应和堆栈中的下一个中间件函数,如下所示:

mw1 = function(req, res, next){}.bind(undefined, req, res, mw2)
mw2 = function(req, res, next){}.bind(undefined, req, res, mw3)

The value of next within the scope of mw1 is mw2 .的值next的范围内mw1mw2

You can not only JsDoc the parameter types and descriptions, and but also their expected members.您不仅可以在 JsDoc 中获取参数类型和描述,还可以获取它们的预期成员。

/**
 * 
 * @module myMiddleware
 * @function
 * @param req {Object} The request.
 * @param res {Object} The response.
 * @param req.params.foo {String} The foo param.
 * @param req.query.bar {String} The bar query.
 * @param req.body {Object} The JSON payload.
 * @param {Function} next
 * @return {undefined}
 */
function foo(req, res, next){
}

req , res and next are all objects, and a middleware usually doesn't return, so the following may be used. reqresnext都是对象,中间件通常不会返回,因此可能会使用以下内容。

/**
 * My Middleware
 * @name MyMiddleWare
 * @function
 * @param {Object} req
 * @param {Object} res
 * @param {Object} next
 */

[2021-03-02 Update] Original answer is like 100% JSDOC + 0% typescript, but I found a 20% JSDOC + 80% typescript (pure definition) solution. [2021-03-02 更新] 原来的答案是 100% JSDOC + 0% typescript,但是我找到了一个 20% JSDOC + 80% typescript(纯定义)的解决方案。 In typescript github , it mentioned this method.typescript github 中,它提到了这种方法。 See the final paragraph in post.请参阅帖子中的最后一段。

I combine other answer and modify some code,我结合其他答案并修改了一些代码,
it could include all of the methods/properties defined on express.Request and event custom request body.它可以包括在express.Request和事件自定义请求正文中定义的所有方法/属性。
It could not only use in request.body , but also support in req.query .它不仅可以在request.body使用,还可以在req.query
That because express.Request support generics, so we could use this in JSDoc.那是因为express.Request支持泛型,所以我们可以在 JSDoc 中使用它。

First, remember to install @types/express with npm install --save-dev @types/express .首先,记住安装@types/expressnpm install --save-dev @types/express

Second, setup like following code.其次,设置如下代码。

// @ts-check
/**
 * @typedef {object} showRequestBody
 * @property {string} name this is name in request body
 * @property {number} age this is age in request body
 * 
 * @typedef {object} showRequestQuery
 * @property {string} name this is name in query
 * @property {number} age this is age in query
 * 
 * @param {import('express').Request<{}, {}, showRequestBody, showRequestQuery>} req
 * @param {import('express').Response} res 
 * @param {import('express').NextFunction} next 
 */
exports.show = function(req, res, next) {
};

Note: I use it in vscode.注意:我在 vscode 中使用它。
I leave answer here, and I hope this will help other people also have this question.我在这里留下答案,我希望这会帮助其他人也有这个问题。


other methods/properties defined on express.Request , for example req.headers express.Request定义的其他方法/属性,例如req.headers


req.body hint req.body提示


req.query hint req.query提示

20% JSDOC + 80% typescript 20% JSDOC + 80% 打字稿

The following example doesn't need tsconfig.json or install extra tsc .以下示例不需要tsconfig.json或安装额外的tsc
But, you couldn't use jsdoc to generate documentation.但是,您不能使用 jsdoc 来生成文档。

With import + export definition带导入+导出定义

If you want to extend interface with importing some module, you need to use export in definition.如果要通过导入某个模块来扩展接口,则需要在定义中使用 export。 Then import it in JSDOC.然后在JSDOC中导入。

在此处输入图片说明

在此处输入图片说明

Without import + export definition没有导入+导出定义

If you don't want to import custom definition in JSDOC, you could just define the interface without import and export.如果你不想在 JSDOC 中导入自定义定义,你可以只定义接口,而不需要导入和导出。 Then, you could directly use it in JSDOC.然后就可以直接在JSDOC中使用了。

在此处输入图片说明

在此处输入图片说明

Extend the express module扩展 express 模块

There is another way to build custom interface, just use declare module to extend the interface.还有另一种构建自定义接口的方法,只需使用declare模块扩展接口即可。 You could even define custom method.您甚至可以定义自定义方法。

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

The only thing you need to change is the @param {Function} next to @param {Object} .您唯一需要更改的是@param {Object}旁边的@param {Function} @param {Object} Also, @return should describe what the function returns;另外, @return应该描述函数返回的内容; eg, (Object, Array) or a combination ({Object|Null})例如, (Object, Array)或组合({Object|Null})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何jsdoc注释BackboneJS代码? - How to jsdoc annotate BackboneJS code? 如何在 JSDoc 中使用可选属性注释匿名对象 - How to annotate anonymous object with optional property in JSDoc 使用 JSDoc 如何注释解构的重命名函数参数? - Using JSDoc how would I annotate a destructured renamed function argument? 如何在 JSDoc 中使用 Function 类型注释 object 类型,该类型具有可变数量的 arguments? - How to annotate an object with Function type that has variable number of arguments in JSDoc? 如何在JSDoc中注释“@ readonly-but-modified-internal”成员/属性? - How to annotate “@readonly-but-modified-internally” members / properties in JSDoc? Express JS路由器中间件 - Express JS Router middlewares 如何在其他文件中设置 express 中间件? - How do I set middlewares on express in other file? Express服务器如何与Wepback中间件一起使用以实现热重装? - how does express server work with wepback middlewares to enable hot reloading? 你能解释一下错误处理如何与 Express 中间件一起工作吗? - Could you explain how error handling works with Express middlewares? 如何为我的所有Express中间件设置默认拒绝承诺行为? - How to set default rejected promise behavior for all my Express middlewares?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM