安装 Sentry 进行错误跟踪

  • 性能监控(trace)
  • 错误定位(source-map)

1. 安装并配置命令行工具

安装 sentry-cli

1
2
# 安装 命令行工具 / 全局安装
$ npm install @sentry/cli -g

如果安装比较慢可以查看 Npm FAQ

新建配置文件 .sentryclirc

在工程根目录下新建 .sentryclirc 文件, sentry_cli 会默认读取文件,配置如下:

1
2
3
4
5
6
7
[defaults]
url=http://sentry.demo-domain.com
org='组织名'
project='项目名称'

[auth]
token=AccountApiToken

Token 的获取地址 Account > API> Create New Token

如果这里上传 source-map , 则需要 project:releases权限

获取项目 Dsn

dsn 是项目上报错误的地址, 该 dsn(数据源)告诉 SDK 将事件发送到哪里。如果未提供此值,SDK 将尝试从 SENTRY_DSN 环境变量中读取它。如果该变量也不存在,则 SDK 将不会发送任何事件。请在 sentry.io 中查看“设置”->“项目”->“客户端密钥(DSN)”

2. 使用 Webpack 组件包配置

2.1 Umi/React 示例

1) 项目安装

Sentry 通过在应用程序的运行时中使用 SDK 捕获数据。使用 yarn 或 npm 将 Sentry SDK 添加为依赖项

1
2
$ npm install --save-dev @sentry/webpack-plugin
$ npm install --save @sentry/react

2) 项目对接 Dsn

在项目的根 layout 文件中引入并初始化 Sentry React SDK 和 ErrorBoundary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from "react";
import * as Sentry from "@sentry/react";

// 这里的版本号使用 env+version 方式, 更方便定位问题
Sentry.init({
dsn: "数据源",
release: "版本号",
environment: "环境,比如生产或者测试",
});

const Base = (props: any) => {
const children = props.children;
return (
<Sentry.ErrorBoundary fallback={() => console.log("An error has occurred")}>{children}</Sentry.ErrorBoundary>
);
};

export default Base;

注: ErrorBoundary 是定义遇到错误时应用程序行为的必要工具。该@sentry/react 软件包公开了一个 ErrorBoundary 组件,该组件自动将 JavaScript 错误从 React 组件树内部发送到 Sentry。像常规 React 组件一样使用 ErrorBoundary . 完成此操作后,Sentry 会自动捕获所有未处理的异常

可以通过在应用程序内的某个地方引发异常来触发开发环境中的第一个事件。例如,呈现一个按钮:

1
return <button onClick={methodDoesNotExist}>Break the world</button>;

3) 部署 source-map

构建项目时,我们会将代码进行压缩混淆,为了在进行日志分析的时候更清楚看到错误发生的原因,我们要对代码进行还原,因此需要 sourcemap 文件,使用 Sentry 的 Webpack 插件在项目构建时会自动上传 sourcemap 文件. 此操作需要身份认证, 这里会使用到之前配置的 sentry-cli 以及其 Token

在 umirc.ts 配置文件中引入并使用

配置文件中增加 SentryWebpackPlugin 和 devtool 配置项, devtool 值设置为”source-map”.

注意 : 这里的版本号使用的是 env + version 的方式, 更方便定位问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
devtool: "source-map",
chainWebpack(config : any, { webpack }: { webpack: any }) {
config.plugin('sentry').use(SentryWebpackPlugin, [
{
include: './dist',
release: `${env}-${version}`,
ignore: ['node_modules'],
org: 'org',
sourceMapReference: true,
},
]);
}
}

2.2) Vite 安装

1) 安装组件

安装组件, 因为官方没有提供 对 vite 的对接, 所以使用三方插件

1
2
$ yarn add vite-plugin-sentry
$ yarn add @sentry/vue

2) 项目对接 dsn

在主项目入口引入并配置

1
2
3
4
5
6
7
8
9
10
11
import * as Sentry from "@sentry/vue";
import { appMode, appVersion, sentryDsnUrl } from "@/utils/conf";

const app = createApp(App);

Sentry.init({
app,
dsn: sentryDsnUrl,
release: `${appMode}-${appVersion}`,
environment: appMode,
});

3) 部署 source-map

这里需要注意

  1. 开启 sourcemap 才可以上传

build.sourcemap 这个选项是开启 source map 的, 根据实际情况来进行开关

  1. sourceMap 的 UrlPrefix 需要填写正确

plugins.viteSentry.sourceMaps.urlPrefix (为了标识路径), 是根据 ~(访问目录代表网站, ~/ 代表项目部署的目录), 如果是子目录则需要在填写子目录的位置, 例如我的部署目录是 webapp/, 这里应该配置 ~/webapp/assets

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// vite.config.ts
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
return {
...
plugins: [
...
// 使用 NODE_ENV, production 时候才会执行错误搜集
viteSentry({
debug: true,
url: process.env.VITE_SENTRY_URL,
authToken: process.env.VITE_SENTRY_TOKEN,
org: 'dadi',
project: 'proj',
release: `${mode}-${pkgJson.version}`,
deploy: {
env: `${mode}`
},
setCommits: {
auto: false
},
sourceMaps: {
include: [
`build/proj-${mode}/assets`
],
ignore: ['node_modules'],
urlPrefix: '~/assets'
}
})
],
build: {
outDir: `build/proj-${mode}`,
sourcemap: (mode === 'prod' || mode === 'dev'),
...
},
...
}
});

这样在执行打包的时候即可进行 source-map 的上传

1
2
3
4
5
6
7
...
~/assets/vant.31618c38.js (sourcemap at vant.31618c38.js.map)
~/assets/vue3-clipboard-es.f4fdbc1a.js (sourcemap at vue3-clipboard-es.f4fdbc1a.js.map)
Source Maps
~/assets/Auto.f5325f0e.js.map
~/assets/Buy.cca58b67.js.map
...

3 Sentry 性能监控

性能监控是搜集当前项目性能的一个组件工具, 可选安装, 这里简要介绍

3.1 安装跟踪软件包

1
$ yarn add @sentry/tracing

3.2 配置

通过以下两种方式在应用中启用性能监控:

  • tracesSampleRate 统一采样率,设置为 0 和之间的数字 1。(例如,20% 的 transactions 抽样率,设置 tracesSampleRate 为 0.2。)
  • tracesSampler 基于 transactions 本身及其捕获的上下文动态控制采样率(两者同时配置时,优先级高)

1) 自动检测

@sentry/tracing 提供了 BrowserTracing 集成,该 BrowserTracing 集成会为每个页面加载和导航事件生成一个新的事务(transactions),并为每一个 XMLHttpRequest 或 fetch 创建一个 child span(子跨度)。
要启用此自动跟踪,需要在 SDK 配置选项中添加 BrowserTracing integrations 配置.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import * as Sentry from "@sentry/browser";
import { Integrations } from "@sentry/tracing"; // Must import second
Sentry.init({
app,
dsn: sentryDsnUrl,
release: `${appMode}-${appVersion}`,
environment: appMode,
integrations: [
new Integrations.BrowserTracing({
routingInstrumentation: Sentry.vueRouterInstrumentation(router),
tracingOrigins: ["domain.com", "dev.domain.com", /^\//],
}),
],
/**
* 线上环境捕捉 1%, 开发环境捕捉完整
* https://docs.sentry.io/platforms/javascript/guides/vue/configuration/sampling/#setting-a-sampling-function
* @param samplingContext
*/
tracesSampler: (samplingContext) => {
if (appMode === "prod") {
return 0.01;
} else {
return 1;
}
},
});

配置选项

  • tracingOrigins
    tracingOrigins 默认值是[‘localhost’, /^//]。
    JavaScript SDK 将 sentry-trace 标头附加到所有输出 XHR / fetch 请求中,这些请求的目的地在列表中包含字符串或与列表中的正则表达式匹配。如果您的前端向其他域发出请求,则需要在其中添加它,
    以将 sentry-trace 标头传播到后端服务,这是将事务链接在一起作为单个跟踪的一部分所必需的。该 tracingOrigins 选项与整个请求 URL 匹配,而不仅仅是域。使用更严格的正则表达式来匹配 URL 的某些部分,可以确保请求不必 sentry-trace 附加标头。
    例如
    前端应用程序 example.com
    后端服务 api.example.com
    前端应用程序对后端进行 API 调用
    因此,该选项需要这样配置: new Integrations.BrowserTracing({tracingOrigins: [‘api.example.com’]})
    现在发出的 XHR / fetch 请求 api.example.com 将 sentry-trace 附加标头
    您将需要配置 Web 服务器 CORS 以允许 sentry-trace 标头。该配置看起来像”Access-Control-Allow-Headers: sentry-trace”,但是该配置取决于您的设置。如果您不允许 sentry-trace 标题,则该请求可能会被阻止。
  • beforeNavigate
    对于 pageload 和 navigation 事务,BrowserTracing 集成使用浏览器的 window.locationAPI 生成事务名称。需要自定义名称可以提供一个 beforeNavigate 选项,使用此选项可以修改事务名称以使其更通用,例如,命名为 GET /users/12312012 的事务和 GET /users/11212012 都可以重命名 GET /users/:userid,以便它们可以组合在一起。
  • shouldCreateSpanForRequest
    此功能可用于过滤掉不需要的跨度,例如 XHR 的运行状况检查或类似的检查。默认情况下,shouldCreateSpanForRequest 已经过滤掉了除 tracingOrigins 之外的所有.

2) 手动检测

要手动检测代码的某些区域,可以创建事务来捕获它们。
这是适用于所有的 JavaScript 的 SDK(包括后端和前端)和独立工作的的 Express,Http 和 BrowserTracing 集成。

1
2
3
4
5
const transaction = Sentry.startTransaction({ name: "test-transaction" });
const span = transaction.startChild({ op: "functionX" }); // This function returns a Span
// functionCallX
span.finish(); // Remember that only finished spans will be sent with the transaction
transaction.finish(); // Finishing the transaction will send it to Sentry

例如,如果要为页面上的用户交互创建事务,请执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Let's say this function is invoked when a user clicks on the checkout button of your shop
shopCheckout() {
// This will create a new Transaction for you
const transaction = Sentry.startTransaction('shopCheckout');
// set the transaction on the scope so it picks up any errors
hub.configureScope(scope => scope.setSpan(transaction));

// Assume this function makes an xhr/fetch call
const result = validateShoppingCartOnServer();

const span = transaction.startChild({
data: {
result
},
op: 'task',
description: `processing shopping cart result`,
});
processAndValidateShoppingCart(result);
span.finish();

transaction.finish();
}

此示例将向 shopCheckoutSentry 发送事务。交易将包含一个 task 跨度,用于衡量 processAndValidateShoppingCart 花费了多长时间。最后,调用 transaction.finish()完成交易并将其发送给 Sentry。
在为异步操作创建跨度时,还可以利用 Promise。但是跨度必须在 transaction.finish()调用之前完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function processItem(item, transaction) {
const span = transaction.startChild({
op: "http",
description: `GET /items/:item-id`,
});

return new Promise((resolve, reject) => {
http.get(`/items/${item.id}`, response => {
response.on("data", () => {});
response.on("end", () => {
span.setTag("http.status_code", response.statusCode);
span.setData("http.foobarsessionid", getFoobarSessionid(response));
span.finish();
resolve(response);
});
});
});
}

4. QA

1. 出现错误 (http status: 413)

error: API request failed
caused by: sentry reported an error: unknown error (http status: 413)

上传的 sourceMap 太多,有可能会导致 413 Request Entity Too Large 错误, 这里需要更改后端对上传的大小限制即可, 如果是 nginx, 需要在指定的配置段中增加

1
client_max_body_size 20m;

参考

Axios

返回数据的错误处理

官方链接 : 错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
axios.get("/user/12345").catch(function (error) {
if (error.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// 请求已经成功发起,但没有收到响应
// `error.request` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
console.log(error.request);
} else {
// 发送请求时出了点问题
console.log("Error", error.message);
}
console.log(error.config);
});

无网络

无 response 返回

1
2
3
4
5
6
7
8
{
"message": "Network Error",
"name": "Error",
"stack": "Error: Network Error...",
"config": {
// ...
}
}

请求超时

无 response 返回

1
2
3
4
5
6
7
8
9
{
"message": "timeout of 2000ms exceeded",
"name": "Error",
"stack": "Error: timeout of 2000ms exceeded...",
"config": {
// ...
},
"code": "ECONNABORTED"
}

返回错误码

返回 response

1
2
3
4
5
6
7
8
{
"message": "Request failed with status code 401",
"name": "Error",
"stack": "Error: Request failed with status code 401...",
"config": {
...
}
}

response 数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"data": "Unauthorized Jwt.",
"status": 401,
"statusText": "Unauthorized",
"headers": {
"cache-control": "no-cache, private",
"content-type": "text/html; charset=UTF-8"
},
"config": {
...
},
"request": {
...
}
}

对于 config 中的结构格式查看 请求配置

ApiCloud 常见问题(FAQ)

1. 证书错误

证书生成地址见 : iOS 证书及描述文件制作流程

如果证书类型存在错误, 则会出现以下的问题, 这里应该使用开发证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
note: Using new build system
note: Building targets in parallel
note: Planning build
note: Constructing build description
error: Provisioning profile "Ad-Hoc" doesn't include signing certificate "iPhone Developer: Yufei Li (M5L32Z773W)". (in target 'UZApp' from project 'UZApp')
warning: NewsstandKit is deprecated. (in target 'UZApp' from project 'UZApp')
warning: OpenGLES is deprecated. Consider migrating to Metal instead. (in target 'UZApp' from project 'UZApp')
warning: MobileCoreServices has been renamed. Use CoreServices instead. (in target 'UZApp' from project 'UZApp')
warning: GLKit is deprecated. Consider migrating to MetalKit instead. (in target 'UZApp' from project 'UZApp')
warning: AddressBook is deprecated. Consider migrating to Contacts instead. (in target 'UZApp' from project 'UZApp')
warning: AddressBookUI is deprecated. Consider migrating to ContactsUI instead. (in target 'UZApp' from project 'UZApp')
warning: AssetsLibrary is deprecated. Consider migrating to Photos instead. (in target 'UZApp' from project 'UZApp')

** ARCHIVE FAILED **

** EXPORT FAILED **

error: archive not found at path '/uzmap/temp/UiC1Cw5M31nvsNL/ios/UZApp.xcarchive'

[转+] 用 JSDOC 编写 JavaScript 文档

JSDOC 是一个 API 文档生成器,你只需要在代码中添加特定格式的注释,它就可以从注释中为你生成 HTML 文档。

安装

全局安装:

1
$ npm install -g jsdoc

如果你更倾向项目内使用,你也可以选择:

1
$ npm install jsdoc --save-dev

基本使用

使用 JSDOC 非常简单,先为 JavaScript 文件写好注释,然后用 JSDOC 去解析即可:

1
/path/to/jsdoc file1.js file2.js ...

但这种方式只适合少量文件时使用,当文件数量多了,再加上其他参数,维护起来就会非常麻烦。 所以更好的做法是编写一份配置文件 jsdoc.json,然后通过 -c 参数来指定:

1
/path/to/jsdoc -c jsdoc.json

无论 JSDOC 是通过全局安装,还是局部安装,都建议使用 npm scripts 来调用它,即在 package.jsonscripts 中添加命令(这里命名成 build:doc,可以根据自己爱好定义其他名字):

1
2
3
4
5
{
"scripts": {
"doc": "jsdoc -c jsdoc.json"
}
}

这样我们就可以通过 npm run doc 来生成文档了。

如果实现修改文件后自动生成文档,只需要用类似 nodemon 之类的工具,监听指定文件的变化,然后再自动执行 npm run doc 就好了!

配置文件

JSDOC 的配置项非常多,最常用的是下面这些:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"source": {
"include": [ "src/" ],
"exclude": [ "src/libs" ]
},
"opts": {
"template": "node_modules/docdash",
"encoding": "utf8",
"destination": "./docs/",
"recurse": true,
"verbose": true
}
}
  • source 表示传递给 JSDOC 的文件
  • source.include 表示 JSDOC 需要扫描哪些文件
  • source.exclude 表示 JSDOC 需要排除哪些文件
  • opts 表示传递给 JSDOC 的选项
  • opts.template 生成文档的模板,默认是 templates/default
  • opts.encoding 读取文件的编码,默认是 utf8
  • opts.destination 生成文档的路径,默认是 ./out/
  • opts.recurse 运行时是否递归子目录
  • opts.verbose 运行时是否输出详细信息,默认是 false

注释

我们知道,JSDOC 的工作原理是通过分析 JavaScript 文件中的注释来生成 HTML 文档的。 但是,如果想 JSDOC 生成正确的结果,我们需要编写正确格式的注释才行。它接受如下格式的注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* @author Scarlex
* @class
* @name Application
* @description Base Class of Application.
* @param {Element} canvas The canvas dom element.
* @param {Object} options The options of Application. See {@link Option} for detail.
* @return {Application}
*
* @example
* // create your application
* new Application(canvas, options);
*/
export default class Aplication {

/**
* @private
* @function
* @name Application#intialize
* @description Initialize the application.
*/
initialize() {

}
}

这是我们在 JavaScript 中常见的级块注释。 需要注意的是,JSDOC 的解析器要求注释必须以 /** 开头,如果是以 /*/*** 或多于三个星号的注释都会被忽略。

标签 (Tags)

有了这种级块注释,我们就可以在里面根据需要编写文档了。JSDOC 为我们提供了非常丰富的标签,它的解析器会对这些标签进行额外处理。这些标签大概可以分成两类:级块标签和行内标签。

  • 级块标签:位于注释的最顶层。JSDOC 中绝大部分标签都是级块标签。
  • 行内标签:位于级块标签内的标签,如 @link@tutorial

下面介绍一些常见的级块标签:

  • @author 该类/方法的作者。
  • @class 表示这是一个类。
  • @function/@method 表示这是一个函数/方法(这是同义词)。
  • @private 表示该类/方法是私有的,JSDOC 不会为其生成文档。
  • @name 该类/方法的名字。
  • @description 该类/方法的描述。
  • @param 该类/方法的参数,可重复定义。
  • @return 该类/方法的返回类型。
  • @link 创建超链接,生成文档时可以为其链接到其他部分。
  • @example 创建例子。

命名路径 (Namepaths)

不知道你有没有发现,上面例子中是用 Application#initialize 来表示一个实例方法的。如果是静态方法,那应该怎么表示呢?JSDOC 有自己的解析规则:

  • Constructor.Method 表示静态方法
  • Constructor#Method 表示实例方法
  • Constructor~Method 表示内部方法

了解了这些之后,我们就可以用 JSDOC 为 JavaScript 代码编写文档了,快去试试吧!

使用 Docstrap

由于 JSDoc 默认的文档模板比较单调,而 docstrap 提供了 14+种 bootstrap 风格的模板,因此建议下载 docstrap

安装

1
2
$ npm i ink-docstrap
$ yarn add ink-docstrap -D

移除 Docstrap 对 google 字体的引用

由于引用了 google 字体,国内环境下会导致页面卡顿。

打开 node_modules\ink-docstrap\template\static\styles 目录,将所有引用 google 字体的内容删除:

1
@import url("https://fonts.googleapis.com/css?family=Roboto:400,500");

指定模板:在 jsdoc 的配置文件 conf.json 下的 template 选项 配置为 docstrap/template 即可

如果要手动修改模板样式:修改文件

1
docstrap\template\tmpl\details.tmpl

Docstrap 模板配置项说明参考

Docstrap 使用的还是 jsdoc 的配置项,同时新增了几个配置项。打开 node_modules/ink-docstrap/template/jsdoc.conf.json 文件,这里面 templates 那部分就是 Docstrap 新增的配置项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
...
"templates": {
"systemName" : "{string}",
"footer" : "{string}",
"copyright" : "{string}",
"includeDate" : "{boolean}",
"navType" : "{vertical|inline}",
"theme" : "{theme}",
"linenums" : "{boolean}",
"collapseSymbols" : "{boolean}",
"inverseNav" : "{boolean}",
"outputSourceFiles" : "{boolean}" ,
"outputSourcePath" : "{boolean}",
"dateFormat" : "{string}",
"syntaxTheme" : "{string}",
"sort" : "{boolean|string}"
}
...
}

解释下其中几个配置项的作用:

  • outputSourceFiles:是否输出 js 源文件,也就是生成的 jsdoc 里是否显示源 js 文件的链接。不想让用户看到 js 源文件的话,这项改成 false,或者整个 default 项删除也行。
  • systemName:js 产品的名称。也就是生成的 jsdoc 页面上方的名称。这个改成你自己的。
  • copyright:版权信息。
  • navType:导航方式。就是页面上方的 Classes 导航下拉菜单。支持 vertical 和 inline 两种方式。建议用 vertical。inline 我觉得不方便。
  • theme:皮肤模板。默认这个就挺好。Docstrap 现在提供了 13 种效果。感兴趣的,可以自己去看看其它效果:https://github.com/terryweiss/docstrap
  • linenums:是否显示所在行数。比如当前方法位于 js 源文件 12 行。false 的话,就不显示这个信息。
  • collapseSymbols:是否将类,方法,属性等 doc 信息以加号的方式收起。

Docstrap 提供了一个默认的配置文件可供参考:

1
node_modules\ink-docstrap\template\jsdoc.conf.json

创建和编辑 JSDoc 配置文件

JSDoc 提供的默认配置文件在这里:

1
node_modules\jsdoc\gen.json

结合 JSDoc 和 Docstrap 的默认配置,我们创建一个项目使用的配置文件。

在项目目录新建一个 json 文件,如:jsdoc-conf.json,内容参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
"tags": {
"allowUnknownTags": true
},
"source": {
"include": ["src"], //JavaScript 文件(目录)列表
"exclude": ["src/core", "src/ui"], //在 include 中需要过滤的文件(目录)
"includePattern": ".+\\.(js|es)$" //正则过滤符合规则的文件
},
"plugins": ["plugins/markdown"], //使用markdown 插件
"markdown": {
tags: ["file"], //增加额外需要解析的标签
"excludeTags": ["author"], //排除不用解析的标签
"parser": "gfm", //gfm
"hardwrap": true //允许多行
},
"templates": { //模板配置,包含了 DocStrap 的配置参数
//"logoFile": "images/logo.png", //logo 文件路径
"cleverLinks": false,
"monospaceLinks": false,
"dateFormat": "ddd MMM Do YYYY", //当需要打印日期时使用的格式
"outputSourceFiles": true, //是否输出文件源码
"outputSourcePath": true, //是否输出源码路径
"systemName": "Common Modules", //系统名称
"footer": "", //页脚内容
"copyright": "https://lzw.me.", //页脚版权信息
"navType": "vertical", //vertical 或 inline
//docstrap 模板主题。可取值: cosmo, cyborg, flatly, journal, lumen, paper,
//readable, sandstone, simplex, slate, spacelab, superhero, united, yeti
"theme": "cosmo",
"linenums": true, //是否显示行号
"collapseSymbols": false, //是否折叠太长的内容
"inverseNav": true, //导航是否使用 bootstrap 的 inverse header
"protocol": "html://", //生成文档使用的阅读协议
"methodHeadingReturns": true //method 方法标题上是否包含返回类型
},
//命令行执行参数配置。在这里配置了后
//命令行只需要执行: jsdoc -c jsdoc-conf.json 即可
"opts": {
//"template": "templates/default", //使用 JSDoc 默认模板
"template": "./node_modules/ink-docstrap/template", //使用 docstrap 模板
"destination": "./docs/", //输出目录。等同于 -d ./out/
"recurse": true, //是否递归查找。 -r
"debug": true, //启用调试模式。--debug
"readme": "README.md" //要写到文档首页的 readme 文档。-R README.md
}
}

参考如上的示例说明编写你自己的配置。确认无误,在项目目录下执行如下命令,即可生成项目 API 文档:

1
jsdoc -c ./jsdoc-conf.json

注意点:

  1. 只使用配置文件中的 opts 配置命令行参数。即只使用 -c 参数指定配置文件。因为命令行的参数与配置文件中可能出现重叠,那么就会存在优先级、合并等问题。在不清楚这些问题的情况下,可能会出现各种细节的问题。
  2. source 部分的配置,应简洁清晰明了。这里的 include/exclude/includePattern/excludePattern 以及命令行中附带的文件路径,存在着优先级以及合并的问题。
  3. 推荐配置 markdown 插件,这对详细注释很有帮助。
  4. 遇到错误或奇怪的问题时,多查阅官方文档。JSDoc 中文文档
  5. 理解名称路径,有利于书写和生成更合适的文档。
  6. ES6 模块化方式,某些情况下对导出模块的声明,可借助 @alisas 标签。示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* @file test
* @module test
*/

let abc = 'abc...';

/**
* @alias module:test
*/
const test = {
abc: abc
};

export default test;

使用 IDE 编辑器插件快速生成

通过 IDE 插件,在编辑器中可以快速的插入 JSDoc 规范的注释。大型的 IDE 则甚至在内核中已集成相关功能。

例如使用 /** + enter 便可以在 jetbrains 中生成文档

sublime text 插件

DocBlockr (https://github.com/spadgos/sublime-jsdocs)

vscode 插件

add jsdoc comments

使用命令:

1
$ jsdoc -c path/to/conf.json -t ./node_modules/ink-docstrap/template -R README.md -r .

参考