如何从 npm 发布的模块导入流注解、类型和接口
how to import flow annotations, types and interfaces from an npm-published module
我已经通过测试验证了两种模式可以用于从 npm 发布的模块导入流注释、类型和接口。
接下来我将使用以下模块名称:
- 模块A:定义注解、类型和接口
- 模块 B:依赖模块 A 并希望对其进行类型检查,并使用其注释、类型和接口。
模式 1
模块A
对类型和接口使用 export type
语法:
type IComplex ...
interface IMutableComplex ...
export type {IComplex, IMutableComplex}
将所有 *.js
个文件复制为 *.js.flow
。例如。通过在 package.json
:
中添加类似以下内容
"main": "lib/index.js",
"scripts": {
"prepublish": "mkdir -p lib && for f in $(find src/ -iname *.js | cut -c5-) ; do cp src/$f lib/$f.flow; done",
...
},
- 发布模块
模块 B
- 简单地用
npm i --S module-A
声明依赖关系使得注释也可用,因为 js.flow
文件在已发布模块的 lib/
目录中。
使用以下语法导入类型和接口:
import type {IComplex, IMutableComplex} from 'module-A';
模式 2
模块A
在 declarations.js
文件中定义类型、接口和模块,该文件位于 decl
目录(指向 .flowconfig
的 [libs]
部分):
type IComplex = { ...
interface IMutableComplex { ...
declare module "module-A" {
declare function foo(i: number): number;
}
无需将 *.js
文件复制为 prepublish
脚本中的 *.js.flow
- 发布模块
模块 B
- 像以前一样用
npm i --S module-A
声明依赖关系。然而这一次,没有注释、类型和接口可用,因为 "module-A" 不包含任何 *.js.flow
文件,所以 …
- 从"module-A"包中手动获取
declarations.js
文件并将其放置在decl
目录中(从.flowconfig
的[libs]
部分指向
- 无需使用任何语法来导入类型和接口;它们会自动可用。
以上两种模式是我发现并验证它们有效的唯一方法(尽管我找不到全面的文章)。
我的问题是:
- 哪种模式更惯用/更可取?
- 还有其他模式吗?
关于问题 #1,如果 "module-A" 由另一个组织/个人发布,我可以看到 "pattern 2" 是唯一可能的方法。否则,如果一个人发布两个模块,我认为 "pattern 1" 更直接。
您的观察完全正确。这是发布流类型定义的两种方法。没有其他办法,或者更好:官方的迁移计划有点双向,因为目前,不可能强制所有 JS 项目适应流程。
现在,"pattern 2" 描述了我们所说的 'libdef' 文件或 'declaration files'。通过 flow-typed
项目,我们尝试为常见的第三方节点模块供应高质量的 libdef 文件。
这两种模式都有其优点和缺点......供应商 *.flow.js
文件的最大问题是,它们假设了特定版本的流(例如 peerDependency flow-bin 不理解你最新使用的句法)。另一方面,它是一种使类型与实际代码库保持同步的更精简的方法。
无论如何,这两种方式都是有效的,只要确保您的消费者不会被迫更改他们的 flow
版本只是为了您的包裹。
一些其他有用的信息:
flow@0.32
引入了一项名为 flow gen-flow-files
的实验性新功能,它将通过仅复制类型信息而不是整个代码,以更有效的方式创建您的 *.flow.js
。
此外,我创建了一个关于流类型的问题,在这里开始了完全相同的讨论:https://github.com/flowtype/flow-typed/issues/286
干杯
我已经通过测试验证了两种模式可以用于从 npm 发布的模块导入流注释、类型和接口。
接下来我将使用以下模块名称:
- 模块A:定义注解、类型和接口
- 模块 B:依赖模块 A 并希望对其进行类型检查,并使用其注释、类型和接口。
模式 1
模块A
对类型和接口使用
export type
语法:type IComplex ... interface IMutableComplex ... export type {IComplex, IMutableComplex}
将所有
中添加类似以下内容*.js
个文件复制为*.js.flow
。例如。通过在package.json
:"main": "lib/index.js", "scripts": { "prepublish": "mkdir -p lib && for f in $(find src/ -iname *.js | cut -c5-) ; do cp src/$f lib/$f.flow; done", ... },
- 发布模块
模块 B
- 简单地用
npm i --S module-A
声明依赖关系使得注释也可用,因为js.flow
文件在已发布模块的lib/
目录中。 使用以下语法导入类型和接口:
import type {IComplex, IMutableComplex} from 'module-A';
模式 2
模块A
在
declarations.js
文件中定义类型、接口和模块,该文件位于decl
目录(指向.flowconfig
的[libs]
部分):type IComplex = { ... interface IMutableComplex { ... declare module "module-A" { declare function foo(i: number): number; }
无需将
*.js
文件复制为prepublish
脚本中的*.js.flow
- 发布模块
模块 B
- 像以前一样用
npm i --S module-A
声明依赖关系。然而这一次,没有注释、类型和接口可用,因为 "module-A" 不包含任何*.js.flow
文件,所以 … - 从"module-A"包中手动获取
declarations.js
文件并将其放置在decl
目录中(从.flowconfig
的[libs]
部分指向 - 无需使用任何语法来导入类型和接口;它们会自动可用。
以上两种模式是我发现并验证它们有效的唯一方法(尽管我找不到全面的文章)。
我的问题是:
- 哪种模式更惯用/更可取?
- 还有其他模式吗?
关于问题 #1,如果 "module-A" 由另一个组织/个人发布,我可以看到 "pattern 2" 是唯一可能的方法。否则,如果一个人发布两个模块,我认为 "pattern 1" 更直接。
您的观察完全正确。这是发布流类型定义的两种方法。没有其他办法,或者更好:官方的迁移计划有点双向,因为目前,不可能强制所有 JS 项目适应流程。
现在,"pattern 2" 描述了我们所说的 'libdef' 文件或 'declaration files'。通过 flow-typed
项目,我们尝试为常见的第三方节点模块供应高质量的 libdef 文件。
这两种模式都有其优点和缺点......供应商 *.flow.js
文件的最大问题是,它们假设了特定版本的流(例如 peerDependency flow-bin 不理解你最新使用的句法)。另一方面,它是一种使类型与实际代码库保持同步的更精简的方法。
无论如何,这两种方式都是有效的,只要确保您的消费者不会被迫更改他们的 flow
版本只是为了您的包裹。
一些其他有用的信息:
flow@0.32
引入了一项名为 flow gen-flow-files
的实验性新功能,它将通过仅复制类型信息而不是整个代码,以更有效的方式创建您的 *.flow.js
。
此外,我创建了一个关于流类型的问题,在这里开始了完全相同的讨论:https://github.com/flowtype/flow-typed/issues/286
干杯