检测第三方模块调用代码

大多数 JavaScript 应用程序都依赖第三方库。 这节指南会展示,当项目引用外部资源时如何使用 Flow,至于检查第三方的源码,当然不必了。

接口文件#

Flow 支持 接口文件,目的是帮助 Flow 理解那些不是你写的第三方代码。 这些文件定义了一个第三方模块的接口,包括类型,同时又跟第三方库源码分离。 你不需要改变第三方源码就能使用接口文件,同时,你的代码会根据接口文件中的类型作检测。

整个工作流是这样的:

  • 不要碰第三方源码,也不需要给它们加 @flow

  • 给第三方库增加一个或多个接口文件,放在项目下的某个目录内 - 例如 interfaces 目录

  • 接着告诉 Flow 使用这些接口文件,可以通过 flow start --lib <path to your interface files> 命令或者在配置文件 .flowconfig 中指明

[libs]
interfaces/

例子#

演示下整个过程,我们选择 Underscore 库。 下面代码使用了 Underscore:

1
2
3
4
5
6
7
8
9
10
11
12
/* @flow */

var pizzas = [
  { title: 'Margherita', vegetarian: true },
  { title: 'Pepperoni', vegetarian: false },
  { title: 'Four cheese', vegetarian: true },
  { title: 'Hawaiian', vegetarian: false },
];

function vegetarianPizzas() {
  return _.findWhere(pizzas, {vegetarian: true});
}

运行 flow, 毫无意外的出现错误:

underscore_example.js:11:10,10: unknown global name: _

This is because Flow doesn’t know anything about the global variable _. To fix this we need to create an interface file for Underscore. If we set the [libs] configuration to interfaces/, Flow will look for any .js files located inside that directory for declarations.

这是因为 Flow 不认识全局变量 _. 要解决这个问题,需要为 Underscore 创建一个接口文件。 如果我们配置 [libs]interfaces/, Flow 就会查找 interfaces/ 目录下的所有 .js 文件作为接口定义

1
2
3
4
5
6
// interfaces/underscore.js
declare class Underscore {
  findWhere<T>(list: Array<T>, properties: {}): T;
}

declare var _: Underscore;

这里只是描述了 Underscore(部分)接口,忽略了很多其它方法。有了这个接口文件,Flow 也不需要 理解 Underscore 的源码。

如果我们配置好 .flowconfig

[libs]
interfaces/

重新运行 flow,错误没了

$> flow
Found 0 errors

现在你随意修改代码,调用 Underscore 的方法重现错误,然后就能证实现在是根据接口定义文件来检测的。

给一个库定义接口文件的时候,如果你不想 Flow 检测某个值,你可是使用 any 类型。 这让你只关注用的,然后逐步定义接口文件。 查看这篇文档 声明,了解更多详情。

← Prev Next →

You can edit this page on GitHub and send us a pull request!