vue项目配置使用flow类型检查的步骤


Posted in Javascript onMarch 18, 2020

你是否经常在debug那些简单可避免的bug?可能你给函数传参的时候搞错了参数的顺序,或者本来应该传个Number类型的参数,你传了一个String类型?JavaScript的弱类型是这一类bug的罪魁祸首,静态类型语言中不存在此类bug。Flow就是JavaScript的静态类型检查工具,该库的目标在于检查JavaScript中的类型错误,开发者通常不需要修改代码即可使用,故使用成本很低。同时,它也提供额外语法支持,使得开发者能更大程度地发挥Flow的作用。

一、flow的安装

flow可以直接通过npm或者yarn安装。

这里以npm为例:npm install --save-dev flow-bin

安装完成后在package.json中加入下面的脚本

"scripts": {
  "flow":"flow check"
 }

同时还要安装babel编译器,将flow的类型检查代码从代码中剥离,转变成正常的js代码

npm install --save-dev babel-cli babel-preset-flow

在babel配置文件.babelrc中加入

{
 "presets": ["flow"]
}

二、flow使用

1、配置flow

npm run flow init生成flow配置文件.flowconfig

[ignore]
.*/node_modules/.*
.*/test/.*
.*/build/.*
.*/config/.*
[include]

[libs]

[options]
module.file_ext=.vue 
module.file_ext=.js

[ignore]:Flow 默认检查项目目录下所有文件,但是有很多文件必定是我们不想检查的,就像 node_modules、build 等目录下的文件,所以我们需要在将这些目录写在 ignore 配置下。

[include]:所谓的项目目录其实是 .flowconfig 目录,并不是真正的项目目录,如果我们在这个项目中的某个目录下创建一个 .flowconfig,那么 .flowconfig 所在的目录也会变为一个 Flow 项目。那么,如果我们想对当前 Flow 项目以外的文件或者目录进行检查,需要把它们写在 include 配置项中。

[libs]:在项目中,我们可能会用到很多自定义的类型,比如说要记录对象的结构,它可能在每个文件中都会被运用到,我们将其抽取为全局的类型或数据结构,在任何文件都可以使用。为了管理方便,我们将全局类型都定义在一个或多个单纯的目录中统一管理。这里存放的有可能是一个定义好的数据结构,存放的也有可能是根据项目中某个类对应的数据类型。我们将这些文件或目录写在 libs 配置项中,这个配置对于我们使用 Flow 来说很重要。

[options]:这里填写对 Flow 项目的一些配置,配置项以key=value的形式,每行写一个。所有的配置见官方文档

[lints]:官网中没有提到 lints 相关的配置

2、新建一个文件index.js

// @flow 
let a:number = '3';
// @flow或者 /* @flow */,告诉flow检查这个文件

如果不愿意那么麻烦,想检查全部文件,那么可以修改配置文件.flowconfig,在[options]配置项中添加 all=ture。

[ignore]
[include]
[libs]
[options]
all=true
[lints]

[libs] 配置项中的文件不需要添加// @flow,它们都将被检查。

注:在vue单文件组件使用flow需要额外配置:

(1)在.flowconfig文件的[options]中配置.vue文件扩展名,module.file_ext=.vue

(2)在.vue文件中需注释掉template script styled标签

输入npm run flow 执行类型检查。

注:完成设置之后,在终端输入以下命令可以在你的项目根目录以及任何子目录文件夹下进行专门的类型检查:npm run flow check,但是,这并不是最高效的使用方式,因为每次Flow都会重新检查整个项目的所有文件。开发过程中,推荐启动Flow服务:Flow服务的工作方式是增量检查,也就是说它只检查变化的部分。在终端输入以下命令来启动Flow服务:npm run flow,首次运行该命令时,服务启动并且显示最初类型检查结果。这保证了Flow更高效的增量式工作流。然后接下来每次想要知道检测结果,只要输入flow命令即可。开发结束之后,输入npm run flow stop停止服务。

Flow的类型检查是可选的,并不需要一次性检查所有代码。你可以选择你想要检查的文件,只要在对应的JavaScript文件最前面加上带有@flow标识的注释即可:/*@flow*/,当你想在已有项目中加入Flow的时候,该特性特别有帮助。因为你可以一一选择并检测你要的文件,然后修正错误。

三、类型推断

通常,类型检查分为以下两种方式:

通过注释:事先注释好我们期待的类型,Flow就会基于这些注释来评估

通过代码推断:通过变量的使用上下文来推断出变量类型,然后根据这些推断来检查类型

第一种方式,我们需要额外编写只在开发阶段起作用的代码,最后在代码编译打包的阶段被剔除。显然,这种额外添加类型注释的方式增加了工作量。

第二种方式,不需要任何代码修改即可进行类型检查,最小化开发者的工作量。它不会强制你改变开发习惯,因为它会自动推断出变量的类型。这就是所谓的类型推断,Flow最重要的特性之一。

我们来通过一个例子来说明这个特性:

/*@flow*/
function foo(x) {
 return x.split(' ');
}

foo(34);

当你在终端运行npm run flow命令的时候,上述代码会报错,因为函数foo()的期待参数是字符串,而我们输入了数字。错误信息类似如下:

index.js:4
  4:   return x.split(' ');
                ^^^^^ property `split`. Property not found in
  4:   return x.split(' ');
              ^ Number

上述信息清楚地指出了出错位置和错误原因。我们只要将参数变成字符串,即可修正错误。该例想说明的是,因为split()方法只适用于string类型的变量,所以x应该是string,这就是类型推断。

四、空类型

Flow处理null的方式与其他类型库不同。它不会忽略null,这样可以防止了因给变量传了null而导致程序崩溃的错误。

/*@flow*/
function stringLength (str) {
 return str.length;
}
var length = stringLength(null);
Flow会报错。为了防止出错,我们需要单独处理null。


/*@flow*/
function stringLength (str) {
 if (str !== null) {
  return str.length;
 }
 return 0;
}
var length = stringLength(null);

代码中我们引入对null的检查,确保代码能在任何情况下都正常且正确运行。上述代码可以通过Flow的类型检查。

五、类型注释

如上所述,类型推断是Flow最有用的特性之一,不需要编写类型注释就能获取有用的反馈。但在某些特定的场景下,添加类型注释可以提供更好更明确的检查依据。考虑以下代码:

/*@flow*/
function foo(x, y){
 return x + y;
}
foo('Hello', 42);

Flow检查上述代码时检查不出任何错误,因为+即可以用在字符串上,也可以用在数字上,我们并没有明确指出add()的参数必须为数字。

在这种情况下,我们可以借助类型注释来指明期望的类型。类型注释是以冒号:开头,可以在函数参数,返回值,变量声明中使用。如果我们在上段代码中添加类型注释,就会变成如下:

/*@flow*/
function foo(x : number, y : number) : number {
 return x + y;
}
foo('Hello', 42);

现在Flow就能检查出错误,因为函数参数的期待类型为数字,而我们提供了字符串。Flow报错信息类似如下:

index.js:7
  7: foo('Hello', 42);
         ^^^^^^^ string. This type is incompatible with the expected param type of
  3: function foo(x : number, y : number) : number{
                      ^^^^^^ number

如果传入的参数是数字,就不会有错误。类型注释在大型复杂的JavaScript文件中也很有用,它能保证代码按照预期进行。

六、Flow能支持的其他更多类型注释。

其实说到底就是类似java那种强语言类型的写法,给每个变量声明是什么类型,给每个函数声明返回值类型,给每个数组元素声明类型等,就是仿造java的写法,哈哈,java传值不对时就会给你报错一样的道理

1、函数

/*@flow*/
function add(x : number, y : number) : number {
 return x + y;
}
add(3, 4);

上述代码展示了变量类型注释以及函数类型注释。函数add()的参数,以及函数的返回值,期待类型为数字。如果传入其他类型参数,Flow就会检测到错误。

2、数组

var foo : Array<number> = [1,2,3];

数组类型注释的格式是Array<T>,T表示数组中每项的数据类型。在上述代码中,foo是每项均为数字的数组。

3、类

下面展示了类和对象的类型注释模型。唯一需要注意的是,可以在两个类型之间使用或逻辑,用|来间隔。变量bar1添加了必须为Bar类的类型注释。

class Bar{
 x:string;      // x should be string    
 y:string | number; // y can be either a string or a number
 constructor(x,y){
  this.x=x;
  this.y=y;
 }
}

var bar1 : Bar = new Bar("hello",4);

4、对象字面量

对象的类型注释类似于类,指定对象属性的类型。

var obj : {a : string, b : number, c: Array<string>, d : Bar} = {
 a : "hello",
 b : 42,
 c : ["hello", "world"],
 d : new Bar("hello",3)
}

5、Null

若想任意类型,T可以为null或者undefined,只需类似如下写成 ?T 的格式即可。

/*@flow*/
var foo : ?string = null;

此时,foo可以为字符串,也可以为null。

目前我们只对Flow的类型注释做了很浅的探索。一旦你习惯了使用这些基本类型,建议在Flow官网上的类型文档深入了解所有的类型。

七、库定义

我们经常需要引入第三方库,Flow检查时就会抛出错误。但这并不是我们期待的错误。

庆幸的是,我们不需要修改库源码去防止这些报错。我们只需创建一个库定义(libdef)。libdef是包含第三方库声明的JS文件简称。观察下面的例子:

/* @flow */
var users = [
 { name: 'John', designation: 'developer' },
 { name: 'Doe', designation: 'designer' }
];

function getDeveloper() {
 return _.findWhere(users, {designation: 'developer'});
}

Flow会检查出以下错误:

interfaces/app.js:9
  9:   return _.findWhere(users, {designation: 'developer'});
              ^ identifier `_`. Could not resolve name

由于Flow并不认识_,所以会报错。要解决这个问题,我们需要引入Underscore的库定义

1、使用flow-typed

flow-typed仓库包含了众多流行的第三方库的libdef。只需在项目根目录下创建一个名为flow-typed的文件夹,并且下载相关的定义文件即可。为了进一步简化,可以用npm的命令行方式一键获取和安装libdef文件:npm install -g flow-typed

安装成功之后, 运行flow-typed install来检查package.json文件,并且下载所有项目中用到的第三方库的libdef。

2、自定义libdef

如果你用的库并不在flow-typed仓库,你可以创建你自己的libdef。本文不会细谈自定义libdef,因为很少会有人遇到,感兴趣可以查看此文档。

八、剔除类型注释

由于额外添加的类型注释不是正确的JavaScript语法,打包编译的时候需要在源码中剔除。可以通过flow-remove-types来剔除,或者如果你已经用Babel来转译JS,你可以使用Babel preset来移除。我们只讨论第一种方法。

首先需要安装flow-remove-types作为项目依赖库:npm install --save-dev flow-remove-types

然后在package.json文件中添加另一个script入口:

"scripts": {
 "flow": "flow",
 "build": "flow-remove-types src/ -D dest/",
}

上述命令将剔除src文件夹下的所有类型注释,在dist文件夹中保存编译后的版本。编译后的文件就是普通的能运行于浏览器的JavaScript文件。

到此这篇关于vue项目配置使用flow类型检查的步骤的文章就介绍到这了,更多相关vue flow类型检查内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
dreamweaver 安装Jquery智能提示
Apr 02 Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
May 07 Javascript
Javascript delete 引用类型对象
Nov 01 Javascript
JS实现可展开折叠层的鼠标拖曳效果
Oct 09 Javascript
详解Angular的双向数据绑定(MV-VM)
Dec 26 Javascript
基于jQuery实现咖啡订单管理简单应用
Feb 10 Javascript
vue实现简单loading进度条
Jun 06 Javascript
解决v-for中使用v-if或者v-bind:class失效的问题
Sep 25 Javascript
浅谈在vue中使用mint-ui swipe遇到的问题
Sep 27 Javascript
微信小程序BindTap快速连续点击目标页面跳转多次问题处理
Apr 08 Javascript
JS实现查找数组中对象的属性值是否存在示例
May 24 Javascript
浅析webpack-bundle-analyzer在vue-cli3中的使用
Oct 23 Javascript
Vue项目中使用flow做类型检测的方法
Mar 18 #Javascript
JavaScript正则表达式验证登录实例
Mar 18 #Javascript
JS正则表达式验证密码强度
Mar 18 #Javascript
原生js实现密码强度验证功能
Mar 18 #Javascript
JavaScript实现密码强度实时验证
Mar 18 #Javascript
js如何验证密码强度
Mar 18 #Javascript
js验证密码强度解析
Mar 18 #Javascript
You might like
PHP生成带有雪花背景的验证码
2006/10/09 PHP
php列出一个目录下的所有文件的代码
2012/10/09 PHP
ThinkPHP之M方法实例详解
2014/06/20 PHP
php实现简单文件下载的方法
2015/01/30 PHP
不能再简单的无闪刷新验证码原理很简单
2007/11/05 Javascript
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
2012/05/30 Javascript
js 关键词高亮(根据ID/tag高亮关键字)案例介绍
2013/01/21 Javascript
一个JS的日期格式化算法示例
2013/07/31 Javascript
深入理解jQuery 事件处理
2016/06/14 Javascript
浅谈vue中数据双向绑定的实现原理
2017/09/14 Javascript
Node.Js中实现端口重用原理详解
2018/05/03 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
浅析我对JS延迟异步脚本的思考
2020/10/12 Javascript
vue基于Echarts的拖拽数据可视化功能实现
2020/12/04 Vue.js
Python中的数据对象持久化存储模块pickle的使用示例
2016/03/03 Python
matplotlib绘制动画代码示例
2018/01/02 Python
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
2019/08/30 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
Python3 虚拟开发环境搭建过程(图文详解)
2020/01/06 Python
python中安装django模块的方法
2020/03/12 Python
python爬虫学习笔记之pyquery模块基本用法详解
2020/04/09 Python
浅谈django 重载str 方法
2020/05/19 Python
Python3 requests模块如何模仿浏览器及代理
2020/06/15 Python
Python LMDB库的使用示例
2021/02/14 Python
LA MER海蓝之谜美国官网:传奇面霜
2016/08/27 全球购物
英国户外装备和冒险服装零售商:alloutdoor
2018/01/30 全球购物
德国电子产品购物网站:TechInTheBasket德国
2018/12/07 全球购物
新闻专业个人求职信
2013/12/19 职场文书
电大毕业个人生自我鉴定
2014/03/26 职场文书
白血病捐款倡议书
2014/05/14 职场文书
公司爱心捐款倡议书
2014/05/14 职场文书
关于建议书的格式范文
2014/05/20 职场文书
党委书记群众路线对照检查材料思想汇报
2014/10/04 职场文书
2015年高校就业工作总结
2015/05/04 职场文书
人与自然观后感
2015/06/16 职场文书