配置 .d.ts 卷积
本文继续来自 "调用 API 提取器" 页面的教程。建议从那里开始。
简单案例
要启用 .d.ts 卷积生成,您只需在 api-extractor.json 配置文件中将 dtsRollup.enabled
设置为 true。
默认情况下,卷积文件将写入 "<projectFolder>/dist/<unscopedPackageName>.d.ts"
,但您可以使用 dtsRollup.untrimmedFilePath
设置更改此设置。
回想一下,在我们之前的示例中,原始的 package.json 文件如下所示
awesome-widgets/package.json
{
"name": "awesome-widgets",
"version": "1.0.0",
"main": "./lib/index.js",
"typings": "./lib/index.d.ts"
}
要实际使用卷积,我们需要更改 "typings"
字段以指向卷积文件,如下所示
awesome-widgets/package.json
{
"name": "awesome-widgets",
"version": "1.0.0",
"main": "./lib/index.js",
"typings": "./dist/awesome-widgets.d.ts"
}
这会指示 TypeScript 编译器在新位置查找其类型定义。如果您使用 Webpack 来捆绑您的 JavaScript,您可能还需要更改 "main"
以指向您的 "./dist/awesome-widgets.js"
捆绑包,然后您可能可以将整个 lib 文件夹添加到 .npmignore 文件中,并使您的包更小。
一个重要限制
.d.ts 卷积功能目前假定您的包具有一个单一入口点 (mainEntryPointFilePath
设置)。情况并非总是如此。一些项目依赖于基于路径的导入,例如
import { Button } from 'awesome-widgets/lib/Button';
此导入语句正在 awesome-widgets 文件夹树中搜索以查找特定文件。通常,这与卷积不兼容,因为任何导出的声明现在将有两个副本:一个在 lib 文件夹中,一个在卷积文件中。TypeScript 编译器通常不认为重复声明是可以互换的,并且可能会导致一些非常令人困惑的错误消息。
从 API 设计的角度来看,基于路径的导入有一个缺点,即文件夹布局成为您的 API 合同的一部分:例如,如果我们要将 lib/Button 重组为 lib/controls/Button 文件夹,我们现在需要担心这是否会对任何使用基于路径的导入的使用者造成重大更改。TSDoc 项目已经考虑过这个问题,并且其 tsdoc-metadata.json 文件计划最终声明项目正式支持的入口点。它的声明引用表示法已经允许导入路径。
但今天,API 提取器假设您的项目只有一个入口点。(API 提取器开发人员不认为基于路径的导入是最佳实践,因此我们已经从我们所处理的所有数百个 TypeScript 包中删除了它们。因此,此增强功能对于我们来说并不算首要任务。但是,如果社区中的某个人想进行开发,我们一定会提供帮助。)
尽管多个入口点对 .d.ts 卷积来说是一个问题,但幸运的是您仍然可以使用 API 报告文件和文档功能:您只需创建一个虚拟源文件,例如 src/api-extractor.ts,它重新导出您所有不同的入口点,然后将其指定为您的 mainEntryPointFilePath
。这允许 API 提取器分析所有声明,就像它们来自单个入口点一样。
根据发布标签进行修剪
.d.ts 卷积功能还支持“修剪”,即根据其 发布标签(@alpha
、@beta
、@public
或 @internal
)删除不需要的成员。请记住,在 API 提取器的术语中,“beta”并不指整个发布分支的准备就绪程度。相反,我们使用“beta”来描述对各个 API 成员的支持级别。因此,修剪后的版本和未修剪后的版本通常将从完全相同的源文件和完全相同的 Git 分支编译而来。
要启用修剪,请将这些设置添加到您的 api-extractor.json 文件中
dtsRollup.betaTrimmedFilePath
- 指定要生成的 .d.ts 卷积文件的输出路径,该文件将针对“beta”版本进行修剪。此文件将仅包含标记为@public
或@beta
的声明。dtsRollup.publicTrimmedFilePath
- 指定要生成的 .d.ts 卷积文件的输出路径,该文件将针对“public”版本进行修剪。此文件将仅包含标记为@public
的声明。
构建机制由您决定,但我们通常建议在您的 package.json 中,"typings"
字段继续指向未修剪的卷积文件。如果您在一个相关的包集合中工作,这将允许您的包在构建期间继续完全访问未修剪的声明。例如,一个包中的 @internal
函数可能会调用另一个包中的 @internal
函数。修剪后的文件将在构建后、在 npm publish
之前连接起来。
继续我们之前的示例项目,我们可以修改 api-extractor.json 文件以包含以下部分
awesome-widgets/config/api-extractor.json
{
. . .
"dtsRollup": {
"enabled": true,
"untrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>.d.ts",
"betaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-beta.d.ts",,
"publicTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-public.d.ts"
},
}
假设我们将从完全相同的源代码构建和发布三种类型的版本
- 内部版本:版本
1.0.0-dev.0
发布到我们公司私有的 NPM 仓库 - beta 版本:版本
1.0.0-plusbeta
发布到 npmjs.com 仓库,供想要试用预览 API 的消费者使用 - 公开版本:版本
1.0.0
也发布到 npmjs.com 仓库,供编写生产代码的消费者使用
要发布内部版本,我们只需在项目文件夹中运行 npm publish
。
要发布 beta 版本,我们首先需要更新 package.json 中的 "typings"
字段,使其指向 awesome-widgets-beta.d.ts。(或者,我们可以用该文件覆盖 dist/awesome-widgets.d.ts。)然后我们运行 npm publish
。
要发布公开版本,我们首先需要更新 package.json 中的 "typings"
字段,使其指向 awesome-widgets-public.d.ts。(或者,我们可以用该文件覆盖 dist/awesome-widgets.d.ts。)然后我们运行 npm publish
。
许多其他方法也是可能的。您的构建脚本可以根据您的需要使用这些文件。这里描述的方法的优点是,使用者可以根据他们的版本选择轻松地在不同的发布类型之间切换,我们发现当您需要发布一组紧密相关的 NPM 包时,这种方法很有效。