如何开发一个基于-TypeScript-的工具库并自动生成文档

为什么用 TypeScript?TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source. ———— TypeScript 官网1.第一时间发现类型错误据 rollbar 统计,在前端项目中 10 大错误类型如下图所示: 其中有 7 个是类型错误(TypeError): Cannot read property 'xxx' on undefined:无法在 undefined 上读取 xxx 属性,通常出现在 a.b.c 的情况。'undefined' is not an object:undefined 不是对象null is not an object:null 不是对象'undefined' is not a function:undefined 不是函数,通常出现在 a.b.c() 的情况。Object doesn't support propertyCannot read property 'length':无法读取 'length' 属性,本来期望一个数组,但是变量的实际类型却不是数组。Cannot set property of undefined:无法给 undefined 设置属性。除了 7 个 TypeError,还有一个 ReferenceError: ...

July 5, 2019 · 3 min · jiezi

文档生成器-mkdocs

mkdocs 是 Python 一个对 Markdown 非常友好的文档生成器,中文文档地址 使用 mkdocs 我们可以用md 编写自己的文档,而且可以免费部署到 GitHub 。 安装pip install mkdocs 使用 mkdocs.exe new mydocINFO - Creating project directory: mydocINFO - Writing config file: mydoc\mkdocs.ymlINFO - Writing initial docs: mydoc\docs\index.md cd mydoc\d:\code\mydoc lsdocs/ mkdocs.ymld:\code\mydoc mkdocs serveINFO - Building documentation...INFO - Cleaning site directory[I 190528 20:32:49 server:296] Serving on http://127.0.0.1:8000[I 190528 20:32:49 handlers:62] Start watching changes[I 190528 20:32:49 handlers:64] Start detecting changes[I 190528 20:33:06 handlers:135] Browser Connected: http://127.0.0.1:8000/ ...

June 1, 2019 · 3 min · jiezi

使用-apiDoc-为你的Nodejs-API-生成文档

翻译: 疯狂的技术宅原文:https://jonathas.com/document...未经许可,禁止转载! 本文首发微信公众号:前端先锋欢迎关注,每天都给你推送新鲜的前端技术文章 当你为其他开发人员(前端,桌面,移动等)开发 API 时,需要生成一份风格良好的文档,以便他们知道可以使用的内容和方式,这非常重要。 为此,在Node.js项目中,我一直在使用apiDoc,因为它能够从源代码中的注释生成HTML文档。 对于本文,我将使用我开发的 TODO List API 作为示例。你可以从这里克隆或下载它。 路由和注释在我关于使用 mocha 进行测试并使用 istanbul 进行代码覆盖测试的文章中,我在 TODO List API 中显示了 Task 端点的示例: import Task from "../controllers/tasks";export = (app) => { const endpoint = process.env.API_BASE + "tasks"; app.post(endpoint, Task.create); app.delete(endpoint + "/:id", Task.delete); app.get(endpoint + "/:id", Task.getOne); app.get(endpoint, Task.getAll); app.put(endpoint + "/:id", Task.update);};这代表了与系统中任务相关的所有端点。我们怎样才能使用它们呢?使用 API 的开发人员应该向每个端点发送什么数据呢? 到现在为止,他们除了去查看代码之外没有其他方法可以搞清楚,但是这些代码不应该被用作这个目的。 有了 apiDoc,我们可以用注释来生成文档。我的方法是在 routes 目录下的文件中配置的每个端点的前面编写它们。当我提到如何配置和组织我的 Node.js 项目时,如果你不确定我在说什么请 点击这里。 使用注释,我们的任务端点(内部routes/tasks.ts)将如下所示: import Task from "../controllers/tasks";export = (app) => { const endpoint = process.env.API_BASE + "tasks"; /** * @api {post} /api/v1/tasks Create a task * @apiVersion 1.0.0 * @apiName Create * @apiGroup Task * @apiPermission authenticated user * * @apiParam (Request body) {String} name The task name * * @apiExample {js} Example usage: * const data = { * "name": "Do the dishes" * } * * $http.defaults.headers.common["Authorization"] = token; * $http.post(url, data) * .success((res, status) => doSomethingHere()) * .error((err, status) => doSomethingHere()); * * @apiSuccess (Success 201) {String} message Task saved successfully! * @apiSuccess (Success 201) {String} id The campaign id * * @apiSuccessExample {json} Success response: * HTTPS 201 OK * { * "message": "Task saved successfully!", * "id": "57e903941ca43a5f0805ba5a" * } * * @apiUse UnauthorizedError */ app.post(endpoint, Task.create); /** * @api {delete} /api/v1/tasks/:id Delete a task * @apiVersion 1.0.0 * @apiName Delete * @apiGroup Task * @apiPermission authenticated user * * @apiParam {String} id The task id * * @apiExample {js} Example usage: * $http.defaults.headers.common["Authorization"] = token; * $http.delete(url) * .success((res, status) => doSomethingHere()) * .error((err, status) => doSomethingHere()); * * @apiSuccess {String} message Task deleted successfully! * * @apiSuccessExample {json} Success response: * HTTPS 200 OK * { * "message": "Task deleted successfully!" * } * * @apiUse UnauthorizedError */ app.delete(endpoint + "/:id", Task.delete); /** * @api {get} /api/v1/tasks/:id Retrieve a task * @apiVersion 1.0.0 * @apiName GetOne * @apiGroup Task * @apiPermission authenticated user * * @apiParam {String} id The task id * * @apiExample {js} Example usage: * $http.defaults.headers.common["Authorization"] = token; * $http.get(url) * .success((res, status) => doSomethingHere()) * .error((err, status) => doSomethingHere()); * * @apiSuccess {String} _id The task id * @apiSuccess {String} name The task name * * @apiSuccessExample {json} Success response: * HTTPS 200 OK * { * "_id": "57e8e94ea06a0c473bac50cc", * "name": "Do the disehs", * "__v": 0 * } * * @apiUse UnauthorizedError */ app.get(endpoint + "/:id", Task.getOne); /** * @api {get} /api/v1/tasks Retrieve all tasks * @apiVersion 1.0.0 * @apiName GetAll * @apiGroup Task * @apiPermission authenticated user * * @apiExample {js} Example usage: * $http.defaults.headers.common["Authorization"] = token; * $http.get(url) * .success((res, status) => doSomethingHere()) * .error((err, status) => doSomethingHere()); * * @apiSuccess {String} _id The task id * @apiSuccess {String} name The task name * * @apiSuccessExample {json} Success response: * HTTPS 200 OK * [{ * "_id": "57e8e94ea06a0c473bac50cc", * "name": "Do the disehs" * }, * { * "_id": "57e903941ca43a5f0805ba5a", * "name": "Take out the trash" * }] * * @apiUse UnauthorizedError */ app.get(endpoint, Task.getAll); /** * @api {put} /api/v1/tasks/:id Update a task * @apiVersion 1.0.0 * @apiName Update * @apiGroup Task * @apiPermission authenticated user * * @apiParam {String} id The task id * * @apiParam (Request body) {String} name The task name * * @apiExample {js} Example usage: * const data = { * "name": "Run in the park" * } * * $http.defaults.headers.common["Authorization"] = token; * $http.put(url, data) * .success((res, status) => doSomethingHere()) * .error((err, status) => doSomethingHere()); * * @apiSuccess {String} message Task updated successfully! * * @apiSuccessExample {json} Success response: * HTTPS 200 OK * { * "message": "Task updated successfully!" * } * * @apiUse UnauthorizedError */ app.put(endpoint + "/:id", Task.update);};如你所见,我们有 HTTP 方法的类型(post,put,get,delete)、端点地址、api 版本、它需要的权限类型、它需要的参数,还有如果用户是未经授权的应该返回怎样的响应和错误。 ...

May 31, 2019 · 4 min · jiezi

如何使用 eolinker 扫描 GitLab 代码注释自动生成 API 文档?

前言:一般写完代码之后,还要将各类参数注解写入API文档,方便后续进行对接和测试,这个过程通常都很麻烦,如果有工具可以读取代码注释直接生成API文档的话,那会十分方便。此前一直都是在使用eolinker的,但自从去年他们家“注释生成文档”的功能下线后,我就一直活在水深火热当中——真的不想写文档啊,真的好累啊。然而这两天上线后,突然发现这个功能重新上线了!必须给大家安利一波!官网地址:https://www.eolinker.com根据官方的解释,这个功能简单来说就是读取 gitlab(以前应该还能读本地代码) 的 php 代码(截至发文增加支持读取java,更方便了)注释生成 API 文档。下面是官方的操作介绍:1.先在EOLINKER新建项目,随后进入项目概况页,可以在概况页中找到“扫描代码注解生成文档”模块。2.在同步之前我们打开设置看下需要填写什么信息。总共是10个选项,我们来分别看下需要怎么填写:1.代码仓库类型,现在默认只有gitlab,在官方群问了他们的PM,后面应该还会支持github。2.代码仓库地址,gitlab有线上版本和用户自己搭建私有云版本,线上版本可以填写https://gitlab.com,如果是自己部署的gitlab写域名或者IP端口。3.项目ID,gitlab中新建项目后会有一个project ID,填入即可。4.访问私钥,通过gitlab的Access Tokens功能可获取,后面会详细介绍如何获取。5.需要扫描的分支,默认为master。我们也可以新建一个分支。6.需要扫描的API目录路径,建立一个目录作为API目录。7.需要扫描的数据结构目录路径,建立一个目录作为数据结构目录。8.目标语言,目前默认只有PHP,比较可惜只有一个语言,不过我跟他们客服聊天,说是后面更新的语言支持会增加java。9.注解格式,默认为Swagger 2.0,代码注释编写的格式可以按照下面的形式来写,或者参考官方文档http://zircote.com/swagger-ph…比如model的比如controller的10.数据同步方式,目前可选增量更新、全量更新、仅添加新的API三种形式。以上就是需要填写的全部信息。要正确填写这些信息,接下来我们就要转到gitlab进行设置。由于官方没有介绍过Gitlab,那还是由我先介绍下比较合适:gitLab 是一个用于仓库管理系统的开源项目,使用git作为代码管理工具,并在此基础上搭建起来的web服务。gitlab跟github有点类似,都是基于web的git仓库,关于注册gitlab新建账号如何操作的部分我就不多说了,但如果你已经有github账号的话,是可以用github账号登录gitLab的。1.首先要新建项目,这里我新建了一个名为demo code的project。2.新建后已经有一个master的分支,然后在分支下分别建立两个新的目录:我命名为controllers和models,一个作为API目录路径,一个作为数据结构目录路径。3.将写好的php代码上传至分别的目录。可以直接用命令行或者直接将文件上传。4.成功上传代码后,跟着就是获取密钥。在gitlab中,生成密钥需要用到Access Tokens功能。先进入设置页面,通过左边菜单中的Access Tokens功能,填写对应的项目名称,再根据需要,勾选开放的权限,看不懂也可以按照我下面的截图进行勾选,点击绿框后就可以获取个人的密钥了。如下图:5.进行到这一步,我们已经把所有的信息都拿到了,再回到EOLINKER将信息填入,请看下图,注意数据同步方式我选择的是增量更新。那我为什么会选择增量更新呢?而三种数据同步更新区别是什么呢?增量更新:判断已有API的详细信息,添加新的API信息。用注解的数据替换掉现有的数据。部分注解没有的数据,比如mock、参数值可能性、详细文档等等,均会保留。全量更新:在添加新的API的基础上,全量替换现有API内的信息,以注解的为准,不保留注解没有的数据。仅添加新的API:判断接口名称是否已经存在,不存在则插入。听起来很绕,我们来举个例子。Gitlab上的接口只有参数,而导入EOLINKER后会有mock、详细文档等数据。假如现在你的gitlab仓库有ABCD四个接口数据,在EOLINKER有A一个接口数据。下面举个例子介绍下三种数据同步更新的区别, GitLab中的接口只有参数,而导入 EOLINKER 后会有 mock、详细文档等数据。假如现在你的 GitLab 仓库有 ABCD 四个接口,在 EOLINKER 有 A 一个接口。采用“增量更新”后,EOLINKER 上将新增 BCD 三个接口;如果仓库A接口的数据有所更新,那么在保持原有本地A接口的 mock、详细文档数据的同时,本地亦将新增相应更新的数据;采用“全量更新”后,EOLINKER 上将有 ABCD 四个接口;此时本地A 接口所有数据都不保留,而会与仓库中A接口的数据保持一致;采用“仅添加新的 API”后,EOLINKER将以接口名称来判断是否需要添加新的API,因此EOLINKER上将新增 BCD 三个接口;即便 GitLab 上的参数已经改变,但本地原有的A接口数据不变;因此,无论是什么情况都推荐采用增量更新。不过即便你还是误操作了,EOLINKER都会自动生成API历史版本,方便我们回滚文档,操作失误也不怕了。1.根据官方的说明,在设置完成点击立即同步后,文档即会开始进行同步,而同步生成文档所需的时间,则根据代码注释的数据量来决定。2.API文档和对应的分组都被自动生成了,如下图。3.那我们就可以直接编辑修改文档了,实在是方便了很多。补充一句:按照他们的更新速度,目前也已经支持读取gitlab上java代码了,操作步骤跟读取php的步骤类似,这里就不展开说了,还不知道请回头再看一遍文章hhh。总结如果可以通过扫描代码注释自动生成API文档,写完代码注解后就不用再一条一条的写接口文档,现在又有一个理由可以不再使用swagger了。新增的这个功能可以减轻大部分不必要的工作量,虽然现在只能支持gitlab上的php代码和java代码,但后续肯定还会继续支持更多的平台和编程语言代码,持续使用起来将会更加方便和快捷,希望eolinker能够给我们带来更多的惊喜。官网地址:https://www.eolinker.com

March 26, 2019 · 1 min · jiezi

docsify

在开发项目时,想要将md文档统一管理,docsify是不错的选择。无需构建和编译,写完markdown就可以直接发布。快速上手全局安装docsify-cli工具npm i docsify-cli -g初始化项目docsify init ./docs初始文件 index.html 入口文件 README.md 会做为主页内容渲染 .nojekyll 用于阻止 GitHub Pages 会忽略掉下划线开头的文件然后直接用浏览器打开localhost:3000,就可以看到基本的网页框架了。就像酱紫。特性容易使用并且轻量 (~18kB gzipped)智能的全文搜索提供多套主题丰富的 API支持 Emoji兼容 IE10+支持 SSR (example)如果觉得README.md主页面太简陋的话可以自己写。链接文档改成对应的url。

December 29, 2018 · 1 min · jiezi