认识 Flow

Flow 是 facebook 出品的 JavaScript 静态类型检查⼯具。Vue.js 的源码利⽤了 Flow 做了静态类型检查, 所以了解 Flow 有助于我们阅读源码

Flow 的官方文档

为什么⽤ Flow

JavaScript 是动态类型语⾔,它的灵活性有⽬共睹,但是过于灵活的副作⽤是很容易就写出⾮常隐蔽的 隐患代码,在编译期甚⾄看上去都不会报错,但在运⾏阶段就可能出现各种奇怪的 bug。

类型检查是当前动态类型语⾔的发展趋势,所谓类型检查,就是在编译期尽早发现(由类型错误引起 的)bug,⼜不影响代码运⾏(不需要运⾏时动态检查类型),使编写 JavaScript 具有和编写 Java 等强 类型语⾔相近的体验。

项⽬越复杂就越需要通过⼯具的⼿段来保证项⽬的维护性和增强代码的可读性。 Vue.js 在做 2.0 重构的 时候,在 ES2015 的基础上,除了 ESLint 保证代码⻛格之外,也引⼊了 Flow 做静态类型检查。

之所以 选择 Flow,主要是因为 Babel 和 ESLint 都有对应的 Flow 插件以⽀持语法,可以完全沿⽤现有的构建 配置,⾮常⼩成本的改动就可以拥有静态类型检查的能⼒。

Flow 的⼯作⽅式

通常类型检查分成 2 种⽅式:

类型推断:通过变量的使⽤上下⽂来推断出变量类型,然后根据这些推断来检查类型。它不需要任何代码修改即可进⾏类型检查,最⼩化开发者的⼯作量。它不会强制你改变开发习惯,因 为它会⾃动推断出变量的类型。

这就是所谓的类型推断,Flow 最重要的特性之⼀。 通过⼀个简单例⼦说明⼀下

/*@flow*/``
function split(str) {
return str.split(' ')
}
split(11) // 会报错:str.split is not a function // Flow 检查上述代码后会报错,因为函数 split 期待的参数是字符串,⽽我们输⼊了数字

类型注释:事先注释好我们期待的类型,Flow 会基于这些注释来判断。

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

/*@flow*/
function add(x, y){
return x + y
}
add('Hello', 11)

Flow 检查上述代码时检查不出任何错误,因为从语法层⾯考虑, + 即可以⽤在字符串上,也可以⽤ 在数字上,我们并没有明确指出 add() 的参数必须为数字。 在这种情况下,我们可以借助类型注释来指明期望的类型。

类型注释是以冒号 : 开头,可以在函数 参数,返回值,变量声明中使⽤。 如果我们在上段代码中添加类型注释,就会变成如下

/*@flow*/

function add(x:number, y:number): number{
return x + y
}
add(11, 11)

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

上面的例子是针对函数的类型注释。接下来我们来看看 Flow 能支持的一些常见的类型注释。

数组:数组类型注释的格式是 Array<T>T 表示数组中每项的数据类型。在上述代码中,arr 是每项均为数字的数组。如果我们给这个数组添加了一个字符串,Flow 能检查出错误

/*@flow*/

var arr: Array<number> = [1, 2, 3]
arr.push('Hello')

类和对象:类的类型注释格式如上,可以对类自身的属性做类型检查,也可以对构造函数的参数做类型检查。这里需要注意的是,属性 y 的类型中间用 | 做间隔,表示 y 的类型即可以是字符串也可以是数字。

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

/*@flow*/

class Bar {
x: string; // x 是字符串
y: string | number; // y 可以是字符串或者数字
z: boolean; constructor(x: string, y: string | number) {
this.x = x
this.y = y
this.z = false
}
} var bar: Bar = new Bar('hello', 4) var obj: { a: string, b: number, c: Array<string>, d: Bar } = {
a: 'hello',
b: 11,
c: ['hello', 'world'],
d: new Bar('hello', 3)
}

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

/*@flow*/

var foo: ?string = null // 此时,foo 可以为字符串,也可以为 null

Flow 在 Vue.js 源码中的应用

有时候我们想引用第三方库,或者自定义一些类型,但 Flow 并不认识,因此检查的时候会报错。为了解决这类问题,Flow 提出了一个 libdef 的概念,可以用来识别这些第三方库或者是自定义类型,而 Vue.js 也利用了这一特性。

在 Vue.js 的主目录下有 .flowconfig 文件, 它是 Flow 的配置文件

这其中的 [libs] 部分用来描述包含指定库定义的目录,默认是名为 flow-typed 的目录。

这里 [libs] 配置的是 flow,表示指定的库定义都在 flow 文件夹内。我们打开这个目录,会发现文件如下

flow
├── compiler.js # 编译相关
├── component.js # 组件数据结构
├── global-api.js # Global API 结构
├── modules.js # 第三方库定义
├── options.js # 选项相关
├── ssr.js # 服务端渲染相关
├── vnode.js # 虚拟 node 相关
												

vue源码分析—认识 Flow的更多相关文章

  1. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  2. vue 快速入门 系列 —— 侦测数据的变化 - [vue 源码分析]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue 源码分析] 本文将 vue 中与数据侦测相关的源码摘了出来,配合上文(侦测数据的变化 - [基本实现]) 一起来分析一下 vue ...

  3. 前端Vue 源码分析-逻辑层

    Vue 源码分析-逻辑层 预期的效果: 监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值.所以直接跟input相关的处理就有3处 ...

  4. [Vue源码分析] v-model实现原理

    最近小组有个关于vue源码分析的分享会,提前准备一下… 前言:我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎么 ...

  5. Vue源码分析(一) : new Vue() 做了什么

    Vue源码分析(一) : new Vue() 做了什么 author: @TiffanysBear 在了解new Vue做了什么之前,我们先对Vue源码做一些基础的了解,如果你已经对基础的源码目录设计 ...

  6. vue源码分析—Vue.js 源码目录设计

    Vue.js 的源码都在 src 目录下,其目录结构如下 src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── ser ...

  7. Vue 源码分析—— 目录结构

    一,Vue.js 的源码都是在src 目录下,其目录结构如下. 1.compiler 目录包含Vue.js 所有编译相关的代码.它包括把所有模板解析成ast 语法树, ast 语法树优化等功能. 2. ...

  8. vue源码分析—Vue.js 源码构建

    Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下.(Rollup 中文网和英文网) 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.j ...

  9. vue源码分析之new Vue过程

    实例化构造函数 从这里可以看出new Vue实际上是使vue构造函数实例化,然后调用_init方法 _init方法,该方法在 src/core/instance/init.js 中定义 Vue.pro ...

随机推荐

  1. 个人整理的 Windows 下 .NET 开发必装的软件

    注: 最后更新时间:2019-03-15 一..NET 开发 1. 必装 软件名称 说明 下载地址 JetBrains Toolbox JetBrins 全家桶管理工具. 下载地址 JetBrains ...

  2. odoo action方法

    二.动作按钮里面也可以由字段判断: def action_select_sale_order_line(self,cr,uid,ids,date_begin,date_end,context=None ...

  3. WPF 通过透明度遮罩和变换制作倒影效果

      倒影效果 代码 <Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http:/ ...

  4. 暖春许愿季丨i春秋给你送福利

    没有一点点防备 也没有一丝顾虑 就这样出现——暖春许愿季 纳尼?这不是我的歌声里 是i春秋在搞活动 这次准备搞个大的 多大呢 看这里 你许下心愿 我帮你实现 这是一棵神奇的心愿树 是一个畅所欲言之地 ...

  5. springboot实现数据库中数据导出Excel功能

    [转载]原文地址:https://blog.csdn.net/wilson_m/article/details/79021458 功能介绍 网上查找了一堆的数据导出代码,可能是自己基础比较薄弱的原因还 ...

  6. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十二 || 三种跨域方式比较,DTOs(数据传输对象)初探

    更新反馈 1.博友@落幕残情童鞋说到了,Nginx反向代理实现跨域,因为我目前还没有使用到,给忽略了,这次记录下,为下次补充.此坑已填 2.提示:跨域的姊妹篇——<三十三║ ⅖ 种方法实现完美跨 ...

  7. Castle Windsor 的动态代理类如何获取实际类型

    问题 在实际开发过程当中我们可能会针对某些类型使用动态代理技术(AOP),注入了一些拦截器进行处理,但是一旦某个类型被动态代理了,那么就会生成一个代理类.这个时候在该类内部使用 GetType() 方 ...

  8. 【Netty】(6) ---源码ServerBootstrap

    [Netty]6 ---源码ServerBootstrap 之前写了两篇与Bootstrap相关的文章,一篇是ServerBootstrap的父类,一篇是客户端Bootstrap类,博客地址: [Ne ...

  9. 从零开始搭建一个规范的vue-cli 3.0项目

    在这一集我们将讲到如何从安装vue-cli开始,到新建一个本地项目,再到vscode中关于eslint的配置,以及本地项目关联公司远程项目的基本操作. 一,初始化本地项目 1,首先,全局安装vue-c ...

  10. ASP.NET Core 2.2 十八.各种Filter的内部处理机制及执行顺序

    ASP.NET core 的Filter是系统中经常用到的,本文详细分享一下各种Filter定义.执行的内部机制以及执行顺序.(ASP.NET Core 系列目录) 一. 概述 ASP.NET Cor ...