靜態類型檢查—Flow入門

Flow入門

介紹

一個 JAVASCRIPT 靜態類型檢測器javascript

  • Flow 使用類型接口查找錯誤,甚至不須要任何類型聲明。 它也可以準確地跟蹤變量的類型,就像運行時那樣
  • Flow 專爲 JavaScript 程序員設計。 他可以理解經常使用 JS 方言和極具動態的特性
  • Flow 能馬上檢測代碼變化,在開發 JS 時提供快速不斷地反饋

安裝

  1. 在項目中安裝flow npm i -D flow-bin
  2. 在項目中安裝babel插件 npm i -D babel-plugin-transform-flow-strip-types
  3. 在編輯器中安裝flow插件,各個商店應該會有各自對應的插件
  4. 全局安裝flow-typenpm i -g flow-typed,flow-typed是什麼見下面👇

使用

.babelrc添加插件

{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    "transform-decorators-legacy",
    "transform-flow-strip-types"
  ]
}

在根目錄中添加.flowconfig文件

[ignore]
<PROJECT_ROOT>/node_modules/.*
<PROJECT_ROOT>/coverage/.*
<PROJECT_ROOT>/.next/.*

[options]
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json
module.file_ext=.css
module.file_ext=.scss
module.file_ext=.less
module.name_mapper.extension='css' -> 'empty/object'
module.name_mapper.extension='scss' -> 'empty/object'
module.name_mapper.extension='less' -> 'empty/object'

esproposal.decorators=ignore

module.name_mapper='^@src\/\(.*\)$' -> '<PROJECT_ROOT>/\1'

這是我項目中的配置文件,主要作了幾件事css

  1. 忽略一些不須要檢查的文件夾
  2. 指定須要檢查文件的後綴名
  3. 將樣式文件解析成空對象
  4. 運行使用decorator語法
  5. 指定模塊解析方式,由於個人模塊路徑都是@src開頭的

在根目錄中添加flow-typed文件夾

這個文件夾是用來存放第三方或者你本身編寫的定義文件的地方,在flow運行的時候會去讀文件夾裏全部文件的定義,固然你也能夠經過配置文件修改默認文件夾的名字。
好比新建一個flow-typed/global.js文件,來定義一些全局變量java

declare var document: Object;

declare var window: Object;

使用flow檢查文件

新建一個文件src/index.jsnode

// @flow
function concat(a: string, b: string): string {
  return a + b;
}

concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false);  // Error!

經過在文件頭部添加// @flow來告訴flow這是個須要檢查的文件,能夠看到flow是個很自由的工具,尤爲是對已經開發好久的項目來講,能夠一點點使用flow,而沒必要對整個項目進行改造。
一但對參數指定好類型後,flow就能夠開始正常工做了,若是須要flow檢查又沒有定義類型,flow也會提示你去定義。
對於如何去定義各類不一樣的變量、函數,這些在文檔中會有更加詳細的介紹,這裏就不細展開了。程序員

類型的模塊化

怎麼去暴露已經定義好的類型給其餘文件使用呢?npm

  • 新建一個暴露js模塊,類型混合的文件a.js
export type A = {
  name: string,
  value: number
}

export default {
  name: 'a',
  value: 100
}
  • 新建b.js引用a.js
import a from './a.js'
import type { A } from './a.js'

const b: A = {
  ...a,
  name: 'b'
}

export default b

使用第三方庫

// @flow
import _ from 'lodash' // Error

flow會報找不到該模塊,這個時候須要咱們去下載lodash的定義文件,用flow-typed 能夠很方便的管理這些第三方庫的定義文件json

flow-typed

一個查找安裝第三方庫定義文件的管理工具babel

  • 查找

flow-typed search lodashapp

Found definitions:
╔════════╤═════════════════╤═════════════════════╗
║ Name   │ Package Version │ Flow Version        ║
╟────────┼─────────────────┼─────────────────────╢
║ lodash │ v4.x.x          │ >=v0.63.x           ║
╟────────┼─────────────────┼─────────────────────╢
║ lodash │ v4.x.x          │ >=v0.55.x <=v0.62.x ║
╟────────┼─────────────────┼─────────────────────╢
║ lodash │ v4.x.x          │ >=v0.47.x <=v0.54.x ║
╟────────┼─────────────────┼─────────────────────╢
║ lodash │ v4.x.x          │ >=v0.38.x <=v0.46.x ║
╟────────┼─────────────────┼─────────────────────╢
║ lodash │ v4.x.x          │ >=v0.28.x <=v0.37.x ║
╚════════╧═════════════════╧═════════════════════╝
  • 選一個版本安裝flow-typed install lodash@v4.x.x,下載的文件會默認保存在flow-typed/npm文件夾下,而且在flow運行的時候自動加載,這個時候就能解決剛剛’模塊找不到‘的報錯
  • 若是搜索不到對應的定義文件怎麼辦?咱們能夠本身手動新建。
  1. 若是咱們從npm上下了一個clipboard庫使用
  2. 添加對應的定義,新建文件flow-typed/npm/clipboard.js
declare module 'clipboard' {
  declare export default any
}

這裏,我很粗暴的把這個模塊定義成了any類型,固然若是你對模塊熟悉或者想定義的更詳細的話,也能夠把這個模塊的各個屬性定義補充完整。具體怎麼定義,能夠查看文檔,這裏也不展開了。less

常見問題

引入css文件報錯

咱們能夠下載一個空模塊npm i -D empty,而後在配置文件中,把全部的樣式文件指向該模塊下的空對象

[options]
module.name_mapper.extension='css' -> 'empty/object'
module.name_mapper.extension='scss' -> 'empty/object'
module.name_mapper.extension='less' -> 'empty/object'

使用window、document等全局對象報錯

咱們能夠在flow-typed/xxx.js中,聲明這些全局對象的類型

declare var document: Object;

declare var window: Object;

declare var process: Object;

declare function fetch(url: string, option?: any): Promise<any>;

使用fetch報錯,見上👆

使用decorator語法報錯

在配置文件中添加

[options]
esproposal.decorators=ignore

很不幸的是,即便忽略decorator語法報錯,在咱們暴露一些通過修飾器修飾的模塊給其餘文件使用的時候,也會遇到報錯的問題,根本緣由是flow不支持decorator語法的類型檢查,因此除非這個模塊不會被其餘文件使用,可使用decorator語法,否則最好的選擇就是不用decorator語法

最後

感謝閱讀,有錯誤但願能及時指正

相關文章
相關標籤/搜索