摘要:本文主要介紹了解決作為弱類型語(yǔ)言沒(méi)有類型檢查痛點(diǎn)的靜態(tài)類型檢查工具,并且介紹了在中使用的方法,最后介紹了一些常用的語(yǔ)法。
本文主要介紹了解決JS作為弱類型語(yǔ)言沒(méi)有類型檢查痛點(diǎn)的靜態(tài)類型檢查工具 Flow ,并且介紹了在WebStorm中使用Flow的方法,最后介紹了一些常用的Flow語(yǔ)法。
1. 簡(jiǎn)介JS作為一種腳本語(yǔ)言是沒(méi)有類型檢測(cè)的,這個(gè)特點(diǎn)有時(shí)候用著很方便,但在一個(gè)較大的項(xiàng)目中就會(huì)發(fā)現(xiàn)這其實(shí)是一件挺糟糕的特性,因?yàn)楹湍銋f(xié)作的程序員往往不太清楚你所寫的代碼到底哪種類型才是正確的,等到代碼重構(gòu)就比較麻煩。于是基于這個(gè)需求有了Typescript和Flow的產(chǎn)生,今天這里主要介紹Flow。
Flow是一個(gè)由Facebook出品的JavaScript靜態(tài)類型檢查工具,它與Typescript不同的是,它可以部分引入,不需要完全重構(gòu)整個(gè)項(xiàng)目,所以對(duì)于一個(gè)已有一定規(guī)模的項(xiàng)目來(lái)說(shuō),遷移成本更小,也更加可行。除此之外,F(xiàn)low可以提供實(shí)時(shí)增量的反饋,通過(guò)運(yùn)行Flow server不需要在每次更改項(xiàng)目的時(shí)候完全從頭運(yùn)行類型檢查,提高運(yùn)行效率。Flow和Typescript都是給Javascript增加類型檢查的優(yōu)秀解決方案,兩者的簡(jiǎn)單對(duì)比如下:
工具 | Flow | TypeScript |
---|---|---|
公司 | 微軟 | |
star | 16k | 33k |
文檔支持程度 | 中等 | 多 |
優(yōu)點(diǎn) | 自由度高,老項(xiàng)目遷移成本低 | 工程化強(qiáng),社區(qū)活躍,官方支持力度高 |
對(duì)于兩者使用場(chǎng)景差別,可以簡(jiǎn)單總結(jié)為:對(duì)于新項(xiàng)目,可以考慮使用TypeScript或者Flow,對(duì)于已有一定規(guī)模的項(xiàng)目則建議使用Flow進(jìn)行較小成本的逐步遷移來(lái)引入類型檢查。Flow可以幫助找出由于不合理的類型操作引起的錯(cuò)誤,包括運(yùn)算符操作,函數(shù)參數(shù)類型和返回值類型等。Flow也支持自定義類型聲明,泛型聲明等類型語(yǔ)言相關(guān)的操作,詳細(xì)的內(nèi)容可以參考文檔。
引入方法:在需要使用 Flow 進(jìn)行類型檢查的 js 文件開頭加入 // @flow 或者 /* @flow */,即可引入Flow,一個(gè)簡(jiǎn)單例子:
// @flow function square(n: number): number { return n * n; } square("2"); // Error!2. 安裝方法
npm安裝:
npm install --save-dev babel-cli babel-preset-flow flow-babel-webpack-plugin babel-preset-es2015 babel-preset-env babel-plugin-transform-class-properties
我是全局安裝的:
npm install -g babel-cli babel-preset-flow flow-bin flow-babel-webpack-plugin babel-preset-es2015 babel-preset-env babel-plugin-transform-class-properties
在.babelrc文件加入:
{ "presets": ["flow", "es2015"], "plugins": [ "transform-vue-jsx", "transform-runtime", "transform-class-properties" ] }
設(shè)置一下WebStorm:通過(guò) File>Settings>Languages&Frameworks>JavaScript 選擇Flow,F(xiàn)low package可以選擇你項(xiàng)目下的flow-bin,當(dāng)然你也可以全局安裝flow-bin,然后在這里設(shè)置后就可以在每個(gè)項(xiàng)目中都使用Flow了 。
但是flow不能直接在node或?yàn)g覽器環(huán)境中使用,所以我們必須用babel編譯后才能使用,使用File watcher:
在項(xiàng)目目錄下運(yùn)行flow init,會(huì)自動(dòng)生成一個(gè)文件.flowconfig,這個(gè)文件可以配置flow,我的配置:
[ignore] .*/node_modules/.*/build/.* /config/.* [options] module.file_ext=.js module.file_ext=.vue
現(xiàn)在當(dāng)我們?cè)陧?xiàng)目中使用Flow時(shí)WebStorm可以給出智能的提示了。
并且多了一個(gè)窗口 Flow 給出文檔中所有提示:
3. 使用最新的 ECMAScript 標(biāo)準(zhǔn)定義了 7 種數(shù)據(jù)類型: 6種原始類型:Boolean、Null、Undefined、Number、String、Symbol 和 Object
在Flow中也是使用這幾種類型作為標(biāo)注:
使用原始類型:
// @flow function method(x: number, y: string, z: boolean) { // ... } method(3.14, "hello", true);
使用對(duì)象類型:
// @flow function method(x: Number, y: String, z: Boolean) { // ... } method(new Number(42), new String("world"), new Boolean(false));
這里需要注意的是大小寫,小寫的 number 是原始類型,而大寫的 Number 是JavaScript的構(gòu)造函數(shù),是對(duì)象類型的。
Boolean在Flow中,默認(rèn)并不會(huì)轉(zhuǎn)換類型,如果你需要轉(zhuǎn)換類型請(qǐng)使用顯示或隱式轉(zhuǎn)換,例如:
// @flow function acceptsBoolean(value: boolean) { // ... } acceptsBoolean(true); // Works! acceptsBoolean(false); // Works! acceptsBoolean("foo"); // Error! acceptsBoolean(Boolean("foo")); // Works! acceptsBoolean(!!("foo")); // Works!Number
// @flow function acceptsNumber(value: number) { // ... } acceptsNumber(42); // Works! acceptsNumber(3.14); // Works! acceptsNumber(NaN); // Works! acceptsNumber(Infinity); // Works! acceptsNumber("foo"); // Error!null和void
JavaScript兼有 null 和 undefined。Flow將這些視為多帶帶的類型:null 和 void(void表示undefined類型)
// @flow function acceptsNull(value: null) { /* ... */ } function acceptsUndefined(value: void) { /* ... */ } acceptsNull(null); // Works! acceptsNull(undefined); // Error! acceptsUndefined(null); // Error! acceptsUndefined(undefined); // Works!也許類型
也許類型是用于可選值的地方,你可以通過(guò)在類型前添加一個(gè)問(wèn)號(hào)(如 ?string 或者 ?number)來(lái)創(chuàng)建它們。
除了問(wèn)號(hào) ? 后跟著的類型,也許類型也可以是 null 或者 void 類型。
// @flow function acceptsMaybeString(value: ?string) { // ... } acceptsMaybeString("bar"); // Works! acceptsMaybeString(undefined); // Works! acceptsMaybeString(null); // Works! acceptsMaybeString(); // Works!可選的對(duì)象屬性
對(duì)象類型可以具有可選屬性,問(wèn)號(hào) ? 位于屬性名稱后面。
{ propertyName?: string }
除了它們的設(shè)定值類型之外,這些可選屬性也可以被 void 完全省略。但是,他們不能 null。
// @flow function acceptsObject(value: { foo?: string }) { // ... } acceptsObject({ foo: "bar" }); // Works! acceptsObject({ foo: undefined }); // Works! acceptsObject({ foo: null }); // Error! acceptsObject({}); // Works!可選的函數(shù)參數(shù)
函數(shù)可以具有可選參數(shù),其中問(wèn)號(hào) ? 出現(xiàn)在參數(shù)名稱后面。同樣,該參數(shù)不能為 null。
// @flow function acceptsOptionalString(value?: string) { // ... } acceptsOptionalString("bar"); // Works! acceptsOptionalString(undefined); // Works! acceptsOptionalString(null); // Error! acceptsOptionalString(); // Works!文字類型
文字類型使用一個(gè)具體的值作為類型:
function foo(value: 2) {} foo(2); // Work! foo(3); // Error! foo("2"); // Error!
您可以使用這些類型的原始值:
布爾值: true 或 false
數(shù)字:像 42 或 3.14
字符串:像 "foo" 或 "bar"
// @flow function getColor(name: "success" | "warning" | "danger") { switch (name) { case "success" : return "green"; case "warning" : return "yellow"; case "danger" : return "red"; } } getColor("success"); // Works! getColor("danger"); // Works! // $ExpectError getColor("error"); // Error!混合類型 mixed
有時(shí)候我們并不能確定需要的值到底是哪種類型,這時(shí)候我們可以使用混合類型來(lái)表示,但在使用該值之前,我們需要判斷該值到底是哪種類型,否則會(huì)引起錯(cuò)誤:
// @flow function stringify(value: mixed) { // $ExpectError return "" + value; // Error! } stringify("foo");
// @flow function stringify(value: mixed) { if (typeof value === "string") { return "" + value; // Works! } else { return ""; } } stringify("foo");任意類型 any
如果你想要一種方法來(lái)選擇不使用類型檢查器,any 是做到這一點(diǎn)的方法。使用any是完全不安全的,應(yīng)盡可能避免。
例如,下面的代碼不會(huì)報(bào)告任何錯(cuò)誤:
// @flow function add(one: any, two: any): number { return one + two; } add(1, 2); // Works. add("1", "2"); // Works. add({}, []); // Works.接口類型 interface
你可以使用 interface 以聲明您期望的類的結(jié)構(gòu)。
// @flow interface Serializable { serialize(): string; } class Foo { serialize() { return "[Foo]"; } } class Bar { serialize() { return "[Bar]"; } } const foo: Serializable = new Foo(); // Works! const bar: Serializable = new Bar(); // Works!
你也可以使用 implements 告訴Flow,你希望類匹配一個(gè)接口。這可以防止編輯類時(shí)發(fā)生不兼容的更改。
// @flow interface Serializable { serialize(): string; } class Foo implements Serializable { serialize() { return "[Foo]"; } // Works! } class Bar implements Serializable { // $ExpectError serialize() { return 42; } // Error! }數(shù)組類型 Array
要?jiǎng)?chuàng)建一個(gè)數(shù)組類型,可以使用 Array
let arr: Array= [1, 2, 3];
暫時(shí)就介紹這么多,還有一些類型文章中沒(méi)有提到,更多更詳細(xì)的內(nèi)容請(qǐng)?jiān)贔low官網(wǎng)中查看。
4. 移除Flow內(nèi)容因?yàn)镕low的語(yǔ)法并不是標(biāo)準(zhǔn)的JavaScript語(yǔ)法,所以我們要在代碼最終上線前移除Flow相關(guān)的代碼(主要是那些固定類型的描述,如果只是添加了@flow,直接應(yīng)用即可)
flow-remove-types這個(gè)程序會(huì)將你所有標(biāo)有@flow的內(nèi)容進(jìn)行移除。。然后將移除后的代碼生成后指定的目錄下
npm i -g flow-remove-types flow-remove-types src/ --out-dir dist/ # src 源文件地址 # dist 生成后的地址babel+webpack
安裝一個(gè)webpack插件
npm i -D flow-babel-webpack-plugin
然后我們修改 .babelrc 文件,添加如下配置:
{ "plugins": [ "transform-flow-comments" ] }
然后在webpack.config.js或 webpack.dev.config.js、 webpack.prod.config.js、文件中添加:
const FlowBabelWebpackPlugin= require("flow-babel-webpack-plugin") module.exports = { plugins: [ new FlowBabelWebpackPlugin() ] }
在babel編譯JavaScript的同時(shí)也就會(huì)將Flow內(nèi)容進(jìn)行移除了。
網(wǎng)上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學(xué)習(xí)過(guò)程中的總結(jié),如果發(fā)現(xiàn)錯(cuò)誤,歡迎留言指出~
參考:
使用Flow來(lái)檢測(cè)你的JS
vue2.0項(xiàng)目配置flow類型檢查
用flow.js提升前端開發(fā)的體驗(yàn)
Flow靜態(tài)類型檢查及在Vue項(xiàng)目中的使用
如何在項(xiàng)目中使用 flow js
PS:歡迎大家關(guān)注我的公眾號(hào)【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,長(zhǎng)按識(shí)別下面二維碼即可加我好友,備注加群,我拉你入群~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/94209.html
摘要:介紹是個(gè)的靜態(tài)類型檢查工具,由出品的開源碼項(xiàng)目,問(wèn)世只有一年多,是個(gè)相當(dāng)年輕的項(xiàng)目。現(xiàn)在,提供了另一個(gè)新的選項(xiàng),它是一種強(qiáng)靜態(tài)類型的輔助檢查工具。 showImg(https://segmentfault.com/img/bVH6mL?w=1200&h=675); 本章的目標(biāo)是提供一些Flow工具的介紹與使用建議。Flow本質(zhì)上也只是個(gè)檢查工具,它并不會(huì)自動(dòng)修正代碼中的錯(cuò)誤,也不會(huì)強(qiáng)制...
摘要:擴(kuò)展靜態(tài)類型檢查語(yǔ)言與系列等語(yǔ)言有一點(diǎn)很大的不同,就是語(yǔ)言是弱類型語(yǔ)言。但其實(shí)很多開發(fā)人員還是比較喜歡用來(lái)開發(fā)項(xiàng)目,所以開發(fā)出來(lái)幫助語(yǔ)言擴(kuò)展靜態(tài)類型檢查功能,規(guī)避上面提到的問(wèn)題。 js 擴(kuò)展:靜態(tài)類型檢查(facebook flow) js 語(yǔ)言與 java、C 系列等語(yǔ)言有一點(diǎn)很大的不同,就是 js 語(yǔ)言是弱類型語(yǔ)言。js 語(yǔ)言的這個(gè)特性可能讓大家覺(jué)得 js 很自由,沒(méi)有強(qiáng)制性的約束...
摘要:一是一種弱類型動(dòng)態(tài)類型檢查的語(yǔ)言。動(dòng)態(tài)類型與靜態(tài)類型的核心區(qū)別動(dòng)態(tài)類型的類型檢查是是在代碼運(yùn)行的時(shí)候進(jìn)行的,靜態(tài)類型的類型檢查則是在編譯時(shí)進(jìn)行。 一、js是一種弱類型、動(dòng)態(tài)類型檢查的語(yǔ)言。 弱類型:在定義變量時(shí),可以為變量定義復(fù)制任何數(shù)據(jù),變量的數(shù)據(jù)類型不是固定死的,這樣的類型叫做弱類型。 var a = 10; a = abc; a = []; a = function() {}...
摘要:原文鏈接翻譯于今天我們興奮的發(fā)布了的嘗鮮版,一個(gè)新的靜態(tài)類型檢查器。為添加了靜態(tài)類型檢查,以提高開發(fā)效率和代碼質(zhì)量。這最終形成一個(gè)高度并行增量式的檢查架構(gòu),類似。知道縮小類型范圍時(shí)做動(dòng)態(tài)檢查的影響。 原文鏈接:https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-java...
閱讀 2598·2021-07-26 23:38
閱讀 3495·2019-08-30 13:10
閱讀 2390·2019-08-29 18:33
閱讀 2380·2019-08-29 16:12
閱讀 1073·2019-08-29 10:59
閱讀 1851·2019-08-26 17:40
閱讀 888·2019-08-26 11:59
閱讀 875·2019-08-26 11:41