支持在JSDoc文档的JS代码上使用Sphinx
项目描述
为什么
当你编写一个JavaScript库时,你如何向人们解释它?如果它是一个用户熟悉的领域的较小项目,JSDoc的字母表顺序的例程列表可能就足够了。但在一个较大的项目中,穿插散文与您的API文档很有用,而无需复制和粘贴内容。
sphinx-js 允许您在 JS 项目中使用业界领先的 Sphinx 文档工具。它提供了一系列指令,模仿了以 Python 为中心的 autodoc 指令,用于将 JSDoc 格式的文档拉入 reStructuredText 页面。而且,因为您可以在代码中继续使用 JSDoc,您将与您的其他 JS 工具(如 Google 的 Closure Compiler)保持兼容。
sphinx-js 还与 TypeScript 兼容,使用 TypeDoc 工具代替 JSDoc,并输出所有预期的类型信息。
设置
安装 JSDoc(如果您正在编写 TypeScript,则安装 TypeDoc)。该工具必须在您的 $PATH 上,因此您可能希望全局安装它
npm install -g jsdoc
…或者…
npm install -g typedoc
已知 JSDoc 3.6.3 和 4.0.0 以及 TypeDoc 0.15.0 可以正常工作。
安装 sphinx-js,这将作为依赖项拉入 Sphinx 本身
pip install sphinx-js
通过运行 sphinx-quickstart 并回答它的问题,在您的项目中创建一个文档文件夹
cd my-project sphinx-quickstart Please enter values for the following settings (just press Enter to accept a default value, if one is given in brackets). Selected root path: . You have two options for placing the build directory for Sphinx output. Either, you use a directory "_build" within the root path, or you separate "source" and "build" directories within the root path. > Separate source and build directories (y/n) [n]: The project name will occur in several places in the built documentation. > Project name: My Project > Author name(s): Fred Fredson > Project release []: 1.0 If the documents are to be written in a language other than English, you can select a language here by its language code. Sphinx will then translate text that it generates into that language. For a list of supported codes, see https://sphinx-doc.cn/en/master/usage/configuration.html#confval-language. > Project language [en]:
在生成的 Sphinx conf.py 文件中,通过将其添加到 extensions 来启用 sphinx_js
extensions = ['sphinx_js']
如果您要记录 TypeScript,请将 js_language = 'typescript' 也添加到 conf.py 中。
如果您的 JS 源代码不在项目的根目录,请在 conf.py 中单独添加 js_source_path = '../somewhere/else'。您的 JS 源代码树根应该位于该设置所指的位置,相对于 conf.py 文件。默认值 ../ 适用于在项目根目录中存在 docs 文件夹且源代码直接位于根目录的情况。
如果您有特殊的 JSDoc 或 TypeDoc 配置,请将 jsdoc_config_path = '../conf.json'(例如)也添加到 conf.py 中。
如果您只记录 JS 或 TS 以及没有其他语言(如 C),则可以在 conf.py 中将您的“主域”设置为 JS
primary_domain = 'js'
(即使您正在编写 TypeScript,域也是 js。)然后您可以在下面的指令中省略所有的“js:”前缀。
使用
简而言之,在 Sphinx 项目中,使用以下指令来拉入您的 JSDoc 文档,然后告诉 Sphinx 在您的文档目录中运行 make html 以渲染所有内容。如果您从未使用过 Sphinx 或编写过 reStructuredText,这里是其 教程的下一部分。为了快速入门,只需将内容添加到 index.rst,直到您证明一切正常。
autofunction
首先,使用标准 JSDoc 格式记录您的 JS 代码
/** * Return the ratio of the inline text length of the links in an element to * the inline text length of the entire element. * * @param {Node} node - Types or not: either works. * @throws {PartyError|Hearty} Multiple types work fine. * @returns {Number} Types and descriptions are both supported. */ function linkDensity(node) { const length = node.flavors.get('paragraphish').inlineLength; const lengthWithoutLinks = inlineTextLength(node.element, element => element.tagName !== 'A'); return (length - lengthWithoutLinks) / length; }
然后,使用 sphinx-js 指令引用您的文档。我们的指令与 Sphinx 的标准 autodoc 指令非常相似。您可以仅指定函数的名称…
.. js:autofunction:: someFunction
…那么,一个格式良好的文档块将显示在您的文档中。
您还可以添加自己的显式参数列表,如果您想注明可选参数的话
.. js:autofunction:: someFunction(foo, bar[, baz])
参数属性和解构参数也工作得很好,使用 标准的 JSDoc 语法
/** * Export an image from the given canvas and save it to the disk. * * @param {Object} options Output options * @param {string} options.format The output format (``jpeg``, ``png``, or * ``webp``) * @param {number} options.quality The output quality when format is * ``jpeg`` or ``webp`` (from ``0.00`` to ``1.00``) */ function saveCanvas({ format, quality }) { // ... }
提取默认参数值也正常工作。这些行为如预期,但有几点需要注意
/** * You must declare the params, even if you have nothing else to say, so * JSDoc will extract the default values. * * @param [num] * @param [str] * @param [bool] * @param [nil] */ function defaultsDocumentedInCode(num=5, str="true", bool=true, nil=null) {} /** * JSDoc guesses types for things like "42". If you have a string-typed * default value that looks like a number or boolean, you'll need to * specify its type explicitly. Conversely, if you have a more complex * value like an arrow function, specify a non-string type on it so it * isn't interpreted as a string. Finally, if you have a disjoint type like * {string|Array} specify string first if you want your default to be * interpreted as a string. * * @param {function} [func=() => 5] * @param [str=some string] * @param {string} [strNum=42] * @param {string|Array} [strBool=true] * @param [num=5] * @param [nil=null] */ function defaultsDocumentedInDoclet(func, strNum, strBool, num, nil) {}
您甚至可以添加额外的内容。如果您这样做,它将出现在任何提取的文档下方
.. js:autofunction:: someFunction Here are some things that will appear... * Below * The * Extracted * Docs Enjoy!
js:autofunction 拥有一个选项,即 :short-name:,对于实现细节不希望暴露的链式API来说,这个选项非常有用。当你在类方法中使用它时,包含的类在文档中不会被提及,函数将在索引中显示其简称,并且交叉引用也必须使用简称(:func:`someFunction`)。
.. js:autofunction:: someClass#someFunction :short-name:
autofunction 还可以用于使用 @callback 标签 定义的回调。
虽然实验性地支持将 autofunction 用于文档化 @typedef 标签,但结果将被格式化为函数样式,并且 @property 标签将误导性地归入“参数”标题下。不过,这总比没有好,直到我们能够正确地处理它。
autoclass
我们提供了一个 js:autoclass 指令,它通过拼接类的注释和构造函数注释来文档化类。它共享了 js:autofunction 的所有功能,甚至可以使用相同的 :short-name: 标志,这对于内部类来说非常有用。使用它的最简单方法是调用它的 :members: 选项,这将自动文档化你类中所有的公共方法和属性。
.. js:autoclass:: SomeEs6Class(constructor, args, if, you[, wish]) :members:
你可以通过以下方式添加私有成员…
.. js:autoclass:: SomeEs6Class :members: :private-members:
隐私由 JSDoc 的 @private 标签或 TypeScript 的 private 关键字确定。
使用 :exclude-members: 标签通过名称排除某些成员。
.. js:autoclass:: SomeEs6Class :members: :exclude-members: Foo, bar, baz
或者明确列出你想要列出的成员。我们将尊重你的排序。
.. js:autoclass:: SomeEs6Class :members: Qux, qum
在明确列出成员时,你可以包括 * 来包含所有未提及的成员。这有助于控制某些元素的排序,而不必包含详尽的列表。
.. js:autoclass:: SomeEs6Class :members: importMethod, *, uncommonlyUsedMethod
最后,如果你想要完全控制,可以通过嵌入 js:autofunction 或 js:autoattribute 逐个拉取你的类成员。
.. js:autoclass:: SomeEs6Class .. js:autofunction:: SomeEs6Class#someMethod Additional content can go here and appears below the in-code comments, allowing you to intersperse long prose passages and examples that you don't want in your code.
autoattribute
这对于文档化公共属性很有用。
class Fnode { constructor(element) { /** * The raw DOM element this wrapper describes */ this.element = element; } }
然后,在文档中…
.. autoclass:: Fnode .. autoattribute:: Fnode#element
这也是文档化 ES6 风格的 getter 和 setter 的方法,因为它省略了函数后面的 ()。假设的实践是通常的 JSDoc:只文档化你的 getter/setter 对中的一方。
class Bing { /** The bong of the bing */ get bong() { return this._bong; } set bong(newBong) { this._bong = newBong * 2; } }
然后,在文档中…
.. autoattribute:: Bing#bong
使用路径名避免歧义
如果你在不同文件中有同名的对象,请使用路径名来区分它们。这里有一个特别长的例子
.. js:autofunction:: ./some/dir/some/file.SomeClass#someInstanceMethod.staticMethod~innerMember
你可能已经认识到了来自 JSDoc 名称路径 的分隔符 #.~;在这里它们工作方式相同。
为了简洁,你可以使用任何唯一的后缀,只要它由完整的路径段组成。假设它们在源树中是唯一的,它们都将与上述内容等效。
innerMember staticMethod~innerMember SomeClass#someInstanceMethod.staticMethod~innerMember some/file.SomeClass#someInstanceMethod.staticMethod~innerMember
注意事项
我们使用简单的文件路径,而不是 JSDoc 的 module: 前缀或 TypeDoc 的 external: 或 module: 之一。
我们独家使用简单的反斜杠转义,而不是在路径中途切换转义方案;JSDoc 本身 也在朝这个方向发展。需要转义的字符是 #.~(/,尽管你不需要在开头的 ./ 或 ../ 中转义点。一个极其糟糕的路径可能是一个…
some/path\ with\ spaces/file.topLevelObject#instanceMember.staticMember\(with\(parens
相对路径相对于配置中指定的 js_source_path。不允许绝对路径。
在幕后,sphinx-js会将所有分隔符更改为点,以便...
Sphinx的“缩短”语法工作::func:`~InwardRhs.atMost` 打印为仅仅是 atMost()。(目前,你应该始终使用点而不是其他名称路径分隔符:#~。)
Sphinx索引更具信息性,说明方法属于其类。
通过设置主要域名来节省键盘敲击次数
为了节省一些键盘敲击,您可以在 conf.py 中设置 primary_domain = 'js',然后说(例如)autofunction 而不是 js:autofunction。
TypeScript:获取超类和接口链接以工作
要使类链接到其超类和实现接口,您需要使用 js:autoclass 或 js:class 在某处记录超类(或接口),并在执行时使用类的完整(但带点的)路径
.. js:autoclass:: someFile.SomeClass
不幸的是,Sphinx的 ~ 语法在这些位置不起作用,因此用户将看到文档中的完整路径。
配置参考
- js_language
根据您使用的语言使用“javascript”或“typescript”。默认为“javascript”。
- js_source_path
要扫描的目录列表(非递归)以查找 JS 或 TS 源文件,相对于 Sphinx 的 conf.py 文件。如果只有一个,则可以是一个字符串。如果有多个,则必须指定 root_for_relative_js_paths。默认为“../”。
- jsdoc_config_path
到 JSDoc 配置文件的 conf.py 相关路径,如果您想指定自己的 JSDoc 选项,例如递归和自定义文件名匹配,这很有用。如果使用 TypeDoc,您也可以指向 tsconfig.json 文件。
- root_for_relative_js_paths
相关的 JS 实体路径相对于此路径解析。如果只有一个项,则默认为 js_source_path。
- jsdoc_cache
JSDoc 输出将缓存的文件的路径。如果省略,每次 Sphinx 运行时都会运行 JSDoc。如果您有大量的源文件,则可能有助于配置此值。但请注意:如果您的源代码更改,则不会自动刷新缓存;您必须手动删除它。
示例
使用大多数 sphinx-js 功能的好例子是 Fathom 文档。一个特别有趣的部分是 https://mozilla.github.io/fathom/ruleset.html。单击“查看页面源代码”链接以查看原始指令。
ReadTheDocs 是 Sphinx 文档的官方托管平台,现在作为可选的测试版支持 sphinx-js。将以下内容放在您存储库根目录下的 .readthedocs.yml 文件中
requirements_file: docs/requirements.txt build: image: latest
然后,在 docs/requirements.txt 中放置您想要的 sphinx-js 版本。例如...
sphinx-js==3.1.2
或者,如果您愿意,Fathom 存储库包含一个 Travis CI 配置 和一个 部署脚本,用于使用 sphinx-js 构建文档并将它们发布到 GitHub Pages。您可以自由借用它们。
注意事项
我们不了解内联 JSDoc 结构,如 {@link foo};您现在必须使用 Sphinx 风格的等效项,例如 :js:func:`foo`(或者如果您在 conf.py 中设置了 primary_domain = 'js',则简单地为 :func:`foo`)。
到目前为止,我们理解和转换了JSDoc块标签 @param、@returns、@throws、@example(不包括可选的 <caption>)、@deprecated、@see 及其同义词。其他标签将消失在虚空中。
测试
使用tox运行测试,这将还会安装JSDoc和TypeDoc的指定版本
pip install tox tox
版本历史
- 3.2.2:(2023年9月20日)
移除对Sphinx的版本上限要求。(#227)
停止支持Python 3.7。(#228)
感谢Will Kahn-Greene!
- 3.2.1:(2022年12月16日)
修复对静态函数的xrefs。(#178)
添加对jsdoc 4.0.0的支持。(#215)
感谢xsjad0和Will Kahn-Greene!
- 3.2.0:(2022年12月13日)
在静态方法前添加“static”。
固定Jinja2和markupsafe版本。(#190)
跟踪依赖项;不读取所有文档。这提高了增量更新的速度。(#194)
支持Python 3.10和3.11。(#186)
支持Sphinx >= 4.1.0。(#209)
修复对 js_source_path 配置项的类型警告。(#182)
感谢Stefan ‘hr’ Berder、David Huggins-Daines、Nick Alexander、mariusschenzle、Erik Rose、lonnen和Will Kahn-Greene!
- 3.1.2:(2021年4月15日)
移除对 docutils 的声明依赖,以解决pip的贪婪依赖解析器对Sphinx最新版本的处理方式。当pip安装sphinx-js时失败,因为pip首先看到了我们的“任何版本的docutils”声明(贪婪解析到最新版本,0.17),但后来遇到了Sphinx的似乎新的 <0.17 约束并放弃。当pip的 --use-feature=2020-resolver 成为默认时,我们可以撤销这个操作。
- 3.1.1:(2021年3月23日)
重写后缀树的大部分内容,该树用于路径查找。这修复了几个崩溃问题。
- 3.1:(2020年9月10日)
重新设计语言分析。现在在JSDoc-和TypeDoc生成的JSON与渲染器之间有一个良好的文档记录的中间表示形式。这应该会大大加快合并PR的速度。
重写TypeScript分析引擎的大部分内容,以便将其馈入新的IR。
如果代码库中包含任何重载函数,TypeScript分析以前会崩溃。现在不再发生这种情况;我们现在任意使用每个重载函数的第一个函数签名。
添加对TS类中的静态属性的支持。
支持TS中的可变参数。
支持TS中的交叉类型(foo & bar)。
从类和接口中删除“导出自”模块链接。函数从未有过。让我们看看我们是否会错过它们。
TS对象的路径名现在不再在文件路径段后面使用 ~;现在它们使用 .,就像JS一样。
更一般地说,TS路径名现在与JS路径名一样。在文件名前不再有 external: 前缀,在命名空间名称前不再有 module: 前缀。
TS分析器不再关心当前工作目录是什么。
测试现在只断言它们关心的事情,而不是变得脆弱到禁止任何更改。
不再显示在参数列表中的完全无用的参数,既没有描述也没有类型信息。
除非手动使用 :members: 排序,否则类属性现在列在方法之前。
- 3.0.1:(2020年8月10日)
当在对象路径上遇到 ../ 前缀时不再崩溃。这可能在设置 root_for_relative_js_paths 在JS代码内部时在后台发生。
- 3.0:(2020年7月14日)
与Sphinx 3兼容,该版本需要Python 3。
停止对Python 2的支持。
使sphinx-js不在意当前工作目录是什么,除了TypeScript分析器,它需要进一步的工作。
正确转义RST返回类型。
- 2.8:(2019年9月16日)
正确显示泛型TypeScript类型。将字段放在方法之前。(Paul Grau)
在TypeScript类顶部合并构造函数和类文档。(Sebastian Weigand)
将pytest作为测试运行器。(Sebastian Weigand)
为大型代码库添加JSDoc输出的可选缓存。(Patrick Browne)
修复TypeScript中联合类型的显示。(Sebastian Weigand)
修复从typedoc 0.14.0开始出现的解析破坏。(Paul Grau)
修复TypeScript中的一个数据输入崩溃。(Cristiano Santos)
- 2.7.1:(2018年11月16日)
修复在Windows上有时会发生UTF-8崩溃的问题。#67。
始终使用conf.py的目录作为JSDoc的工作目录。#78。(Thomas Khyn)
- 2.7:(2018年8月2日)
添加实验性TypeScript支持。(Wim Yedema)
- 2.6:(2018年7月26日)
添加对@deprecated和@see的支持。(David Li)
优雅地通知并记录JS可变参数。(David Li)
向代码库添加lint工具。
- 2.5:(2018年4月20日)
使用文档化的@params来帮助填写函数的形式参数列表。这使我们不会错过使用解构的参数。(flozz)
改进JSDoc缺失时的错误报告。
将提取的默认值添加到生成的形式参数列表中。(flozz和erikrose)
- 2.4:(2018年3月21日)
支持@example标签。(lidavidm)
在Windows下工作。在此之前,我们几乎找不到任何文档。(flozz)
正确展开多行JSDoc标签,即使它们有Windows行结束符。(Wim Yedema)
停止对Python 3.3的支持,因为Sphinx也已经停止支持。
修复在Sphinx >=1.7.1下使用recommonmark(用于Markdown支持)时的构建时崩溃。(jamrizzi)
- 2.3.1:(2018年1月11日)
在Windows上找到jsdoc命令,其中它有一个不同的名称。然后修复进程通信,使其不会挂起。
- 2.3:(2017年11月1日)
添加在autoclass :members:选项中说出“*”的能力,这意味着“和我没有明确列出的一切成员”。
- 2.2:(2017年10月10日)
添加对@callback标签的autofunction支持。(krassowski)
添加对@typedef标签的实验性autofunction支持。(krassowski)
当JSDoc找不到任何JS文件时,添加一个友好的错误信息。
更紧密地锁定six,以确保python_2_unicode_compatible肯定可用。
- 2.1:(2017年8月30日)
允许在js_source_path中使用多个文件夹。这对于逐步迁移大型项目非常有用,一次一个文件夹,到JSDoc。引入root_for_relative_js_paths以保持相对路径在多个源路径面前不模糊。
聚合PathTaken错误,并一次性报告它们。这意味着您在清理大型项目时不必重复运行JSDoc。
修复一个bytes vs. strings问题,该问题在Python 3之前的版本中崩溃。(jhkennedy)
容忍具有除“ .js”之外扩展名的JS文件。在此之前,当与自定义JSDoc配置结合使用时,会生成不正确的对象路径名,从而导致虚假的“没有为对象找到JSDoc文档……”错误。
- 2.0.1:(2017年7月13日)
在加载大型的JSDoc输出时,通过先将其写入临时文件来修复虚假的语法错误。(jhkennedy)
- 2.0版本:(2017年5月4日)
处理模糊的对象路径。具有相同JSDoc长名的符号(例如在不同文件中称为“foo”的两个顶级事物)将不再互相影响。引入一个明确的路径约定来引用对象。添加一个真正的解析器来解析它们,而不是我们之前使用的肮脏技巧。向后兼容性略有降低,因为模糊引用现在是一个致命错误,而不是静默地引用JSDoc偶然遇到的最后一个定义。
将所有内容索引到后缀树中,以便可以使用任何唯一的路径后缀来引用一个对象。
使用真实解析器的其他副作用
停止支持“-”作为名称路径分隔符。
不再将名称路径中的转义分隔符错误地转换为点。
否则正确处理路径和转义。例如,我们现在可以处理包含“(”的符号。
修复尝试收集标记为@class的普通旧对象的构造函数参数时的KeyError。
- 1.5.2版本:(2017年3月22日)
修复在警告指定的长名找不到时的崩溃问题。
- 1.5.1版本:(2017年3月20日)
当未显式指定顺序时,按字母顺序对:members:进行排序。
- 1.5版本:(2017年3月17日)
向autoclass添加:members:选项。
添加与其对应的:private-members:和:exclude-members:选项。
进行重大重构,以允许指令类相互通信。
- 1.4版本:(2017年3月10日)
添加jsdoc_config_path选项。
- 1.3.1版本:(2017年3月6日)
容忍在源代码中包装的@args和其他信息字段行。
在Sphinx生成的警告和错误中引用源注释的文件和行。
- 1.3版本:(2017年2月21日)
添加autoattribute指令。
- 1.2版本:(2017年2月14日)
始终执行完整重建;当JS代码已更改但RST文件未更改时,不要留下页面过时。
使Python 3兼容。
添加基本的autoclass指令。
- 1.1版本:(2017年2月13日)
添加:short-name:选项。
- 1.0版本:(2017年2月7日)
初始发布,仅包含js:autofunction。
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定要选择哪个,请了解有关安装软件包的更多信息。
源代码分发
构建版本
sphinx-js-3.2.2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9e3105994dd0aa6d3257b8b4195dca38e335b223bf28dbec8699f1b624b55ad4 |
|
MD5 | 622db5264cc75944c6d5be5daed4cd5d |
|
BLAKE2b-256 | 51a20d8bc324e43e85bdb256a716af23348a01bb5e58d0b5540745d52ef2edc9 |
sphinx_js-3.2.2-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 05d9e5fe7d3ae745e19fd05a5b477218d81c89ab5ab3134f4a65e3ee7b430420 |
|
MD5 | 2255ffaaa14a9b7d98507881114b0c88 |
|
BLAKE2b-256 | 6b57e489ceaef5f1e5284000d274bdc785d7e855ef525c8ce5e382b660de5692 |