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查看。

相關文章
相關標籤/搜索