react源码解析004 - 关于类型检查工具flow

Flow 简介

flow是facebook推出的js类型检查工具。js是一门弱类型语言,没有从语言层面去保证变量类型不匹配的基本错误。flow使得我们能够指定变量的类型,避免此类错误的发生。node

// @flow
function square(n: number): number {
  return n * n;
}

square("2", "2"); // Error!

如图,使用flow以后,square函数的参数和返回值,均可以指定类型。当你在代码中写square('2', '2')的时候,用flow命令一检查,不须要看业务逻辑,就知道调用的参数有错误。react

flow入门

  1. 新建项目,初始化flow配置git

    mkdir flow-demo && cd flow-demo && mkdir src && mkdir lib
  2. 设置编译器github

    yarn add --dev babel-cli babel-preset-flow

    此时会生成package.jsonyarn.lock文件。yarnnpm的替代品,能够加速npm模块的安装,并且能兼容大多数的npm命令。yarn的官网移步这里正则表达式

    而后在根目录新建一个.babelrc文件,并配置flow做为presetsnpm

    {
      "presets": ["flow"]
    }

    其中"flow"就是指刚才安装的babel-preset-flow的简写,省略了babel-preset-json

    此时,你能够用如下命令来作代码编译:babel

    yarn run babel src/ -D lib/

    固然,也能够将这个命令配置到package.json文件中:函数

    {
      "name": "flow-demo",
      "main": "lib/index.js",
      "scripts": {
        "build": "babel src/ -D lib/",
        "prepublish": "yarn run build"
      }
    }
  3. 设置flow工具

    推荐将flow安装到当前项目目录,而不是全局安装。

    yarn add --dev flow-bin

    此时

    运行yarn run flow init生成配置文件.flowconfig
    运行yarn run flow进行代码检查

    运行上述代码时会生成一个可复用的后台进程,以加快后续代码检查的速度。

    注意上面两命令都带上yarn run flow,而不是直接运行flow。区别是yarn run flow调用了本项目中flow-bin的flow命令。

    另外,npm上有一个flow,和这里面的flow是彻底不相关的,不能混淆。

    停用flow后台进程,使用flow stop

    以上示例的源码

flow配置文件.flowconfig

这部分将结合react的.flowconfigflow官方文档进行解析。

flowconfig大概遵循INI文档格式。一个.flowconfig文件,能够包含下以五个部分:

[include]
[ignore] 用正则表达式匹配文件或目录,知足条件的将被flow忽略;<PROJECT_ROOT>表示项目根目录
[libs]
[options]
[version]

[ignore]

[ignore]
# Ignore Docs
<PROJECT_ROOT>/docs/.*
<PROJECT_ROOT>/.*/docs/.*

react的ignore部分,都使用了<PROJECT_ROOT>这种绝对路径的写法。在配置中使用注释,能够在行首加#号。

[ignore]
<PROJECT_ROOT>/.*/node_modules/y18n/.*

不清楚为何react只将node_modules下的y18n忽略,而不是将整个node_modules目录忽略?(TODO)

[libs]

[libs]
./node_modules/fbjs/flow/lib/dev.js
./flow

dev.js只有一行代码:declare var __DEV__: boolean;, react跨项目引用一行代码可见flow项目简直就是应react而生。

说到[libs],就必需要说一说flow的一个重要概念:flow library definition。一个flow library definition文件(简称libdef),就相似于C++中的头文件,是用来定义跨项目可用的全局变量。能够定义全局的Function/Class/Variables/Type/Module。详见flow文档

TODO: flow为何要支持libdef?又是如何使用libdef文件的?

[options]

[options]
# 可选项node|haste,haste已再也不被维护,可react还在用
module.system=haste

# 容许在class中使用static关键字
esproposal.class_static_fields=enable
# 容许在class中使用instance关键字
esproposal.class_instance_fields=enable

# 不容许在class中使用下划线做为私有函数
munge_underscores=false

# 约束的类型,能够用来代替TODO
suppress_type=$FlowFixMe
# 这个正则是什么含义?TODO
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-3]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)

[version]

[version]
^0.41.0

此version是指flow-bin的版本,能够用yarn run flow version查看。

相关文章
相关标签/搜索