Flow简易教程——安装篇

内容预览:
  • 什么是Flow JavaScript是一个弱类型的解释性语言,无法在编译环节进行静...~
  • 不过需要注意的是,无论是babel还是flow-remove-types,他们仅是去除Flo...~
  • 如果你不想手动修改babel的配置,可以使用flow-babel-webpack-plugin这...~


这是一个Flow的简易教程,属于笔者学习Flow并不断踩坑的过程总结。内容大多翻译Flow官网已经笔者自己的实践。

JavaScript是一个弱类型的解释性语言,无法在编译环节进行静态类型校验,这给JavaScript代码重构带来了巨大的困难,有一句话说的好——动态类型一时爽,重构全家火葬场,充分说明动态类型在编码阶段的高效和重构阶段的低效,因此大家都希望能够让JavaScript也具备静态类型检查功能。Flow就是一个用于JavaScript的静态类型检查的工具,最早由Facebook在2014年的Scale大会上推出,它让JavaScript也可以进行静态类型校验的开发工作,同时兼容JavaScript的弱类型、动态类型的特性,让我们可以开发出利于重构JavaScript代码。

Flow看似与微软的TypeScript有些类似,不过笔者看来TypeScript更像是另一门新语言,而Flow则更像是仅给JavaScript增加了用于静态类型检查的注解(甚至可以在完全符合es语法的情况下通过增加注释来做静态类型检测)。与其说Flow是一门语言不如说他说一个工具。目前已经有很多JavaScript项目都是用了Flow开发的,例如:vue2、react生态下的很多项目等。

我们可以在前端开发中使用它,当然你也可以使用在nodejs中,或者在任何你想使用它的地方。

Flow的安装方法很多,这里仅介绍npm安装,事实上Facebook提供了一个新一代node包管理工具——yarn,与Flow算是相同生态下的工具,不过两者使用起来差异不大,因此以下实例均仅基于npm。使用npm安装Flow:

npm install flow-bin -g

Flow的通用使用流程是:

  • 初始化Flow项目
  • 开启Flow的后台进程,这样Flow会自动在每一次文件内容变化的时候执行静态类型校验
  • 使用Flow注释书写JavaScript代码
  • Flow自动检测出关于类型的错误,并提示


初始化Flow


因此第一步是初始化一个项目,安装完flow-bin后就可以初始化一个项目了,如果如上所示将flow-bin安装在全局,则可以使用flow命令:

flow init

这个命令要在工程的根目录下执行,执行后就会出现一个名为.flowconfig的文件,Flow监听文件变化需要一个后台进程,而.flowconfig文件就是告诉这个后台进程应该做什么。

[ignore]

[include]
[libs]
[options]
[version]

如上所示,.flowconfig有5部分组成:

  • [include]告诉Flow那些文件是需要监听的,通常Flow仅会校验项目根目录下拥有Flow注解的文件,使用include可以将工程外的文件也指定进来。
  • [ignore]告诉Flow忽略哪些目录或文件,这些目录里面的文件即使有Flow注解也不会被监听。这很适合给node_modules这样的目录使用,以增加Flow执行效率。
  • [libs]告诉Flow使用哪些库定义(library definitions),至于什么是库定义,笔者准备到了高级篇在介绍。
  • [version]指定Flow的版本



开启Flow的后台进程


Flow的最大好处就是能快速地校验你代码的错误,一旦你初始化好你的工程后,就可以开始启动Flow进程去校验代码了:

flow status

这实际上是启动了一个后台进程,停止这个进程只需执行:

flow stop



使用Flow注释书写JavaScript代码


现在我们就可开始写Flow文件了,我们之前说了,Flow的后缀名也是js,那么Flow是怎么知道一个文件是Flow文件还是JavaScript文件呢?Flow虽然完全兼容JavaScript代码,但是如果JavaScript代码出现了type相关的错误,Flow也会在校验时候提示错误的,而对于JavaScript则是运行时候才去报错。两种虽然都是报错,但是有本质上的区别,因此我们必须让Flow区分出哪些是JavaScript文件,哪些是Flow的文件。

Flow区别JavaScript文件的方式非常简单,就是给文件加注解:

// @flow

// js的代码部分

注意注解前边的注释不能省,而且注解要放到文件的最上面。除了// @flow注解,还可以用/* @flow */

加上注解后,Flow的后台进程就会自动监听这些文件的变化,并对其做静态类型校验。

到此为止,理论上我们每修改一个文件就应该能够看到文件的校验结果,但实际上并没有出现更改后的校验结果。因为flow status是一个后台进程,所有我们看不到校验结果,如果想要获得当前校验结构需要再执行一下flow status,这一次执行速度明显会比第一次快很多。虽然速度快了,但是和我们想要的自动监听并提示还有差距,不过没关系,稍后笔者会告诉大家解决方法。

前面介绍的是基于后台进程做自动执行校验,除此之外还可以通过cli命令进行手动校验:

flow check

这种方法的执行速度要比后台进程方式慢。

通过以上方法我们就实现了静态类型校验的工作,但是想要Flow能够像JavaScript一样运行还需要“编译”一下才行。接下来介绍编译器的安装。

Flow需要“编译”为JavaScript才能运行,因此必须选择一个“编译器”。其实将FLow解析为JavaScript的过程称为编译其实并不准确,因为这个“编译”过程仅仅就是把Flow提供的注解语法去除。Flow目前支持两种去除注解的方法——babelflow-remove-types

flow-remove-types是一个轻量级的专门用于去除Flow注解的命令行工具,而babel大家应该个更加熟悉,它是现在最流行的es6编译工具,而且可以很容易的和webpack等前端自动化工具集成,因此笔者仅介绍基于babel的版本。

不过需要注意的是,无论是babel还是flow-remove-types,他们仅是去除Flow的注解,但是并没有进行Flow的静态类型检测。事实上babel已经提供了一个Flow预设插件组(babel-preset-flow),它的会自动集成一个叫transform-flow-strip-types的babel插件来去除Flow注解,但是这个插件并不进行flow check。如何想让babel进行Flow的静态类型校验,这就需要手动集成另外一个插件——babel-plugin-typecheck

接下来进行具体的babel集成步骤,首先安装babel、babel-preset-flow、babel-plugin-typecheck,而babel这种工具我们可以安装在全局:

npm install -g babel-cli

npm install --save-dev babel-preset-flow babel-plugin-typecheck

然后创建babel的配置文件,在根目录下创建.babelrc,然后选择Flow的预设插件组(flow),并手动加上babel-plugin-typecheck插件:

{

"presets": ["flow"],
"plugins": ["typecheck"]
}

接着我们就可以使用babel编译我们的Flow代码了,例如我们用Flow开发的源代码在src目录,最终输出在dist目录,只需:

babel src/ -d dist/ --watch

这样我就仅需要babel就完成了校验和编译两项工作,从而不需要Flow的初始化和后台进程,而且使用babel的“–watch”功能解决了之前Flow命令行不能同时监听、提示的缺憾。

貌似大功告成,但是其实还有个问题,分别使用flow-binbabel编译如下代码:

function foo(x){

return x * 12; //Flow根据代码,推断foo的x1参数是string类型,string类型不能执行“*”操作,所有这里Flow会报错
}
foo("Hello, world!")

flow-bin会报错,错误类型如注释。而babel则顺利编译。笔者推测为babel-plugin-typecheck仅会对添加了类型注解的变量做类型检验,而不会对未加注解的变量先做推断类型再检验。

除了集成到babel外,我们还希望能够将我们的源代码的编译过程集成到webpack中,实现校验、打包、编译、丑化等工作,以便能够达到一个完整的构建工作流。集成到webpack的过程非常简单,其实就是babel集成到webpack的过程。

先安装webpack,建议将webpack安装到全局,然后安装babel和Flow的loader。

npm install -g webpack

并配置好webpack的配置文件webpack.config.js。因为webpack有模块化打包的功能,所有只要给出指定的入口文件,就能将所有依赖的文件打包成一个文件。例如src下的index.js是我们的入口文件,则:

var path = require('path');

module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname ,'/dist/'),
filename: '[name].js',
},
module: {
loaders: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
}
}

最后只要运行webpack即可。

以上集成仅是个简单例子,我们还需使用webpack做热替换(HMR)交换,并且能够自动刷新页面页面刷新,甚至是和react和vue集成,这些对于熟悉react和vue的朋友都说小case,这里不再具体深入。

如果你不想手动修改babel的配置,可以使用flow-babel-webpack-plugin这个插件,简化babel对flow的配置。

之前的命令行搭配已经很合理了,但是开发时候我们还是更喜欢IDE帮我们提示语法上的错误,事实上Flow可以和几乎所有主流IDE集成,这里仅以webstorm和vscode为例。



和webstorm集成


Flow提供了自己的注解,这算是扩充了es的语法,直接用es的语法检查肯定会报错,首先让我们的webstorm不要对Flow的注解保错,打开file->settings->Language & Framework->JavaScript界面。将JavaScript Version选为Flow,这样webstorm就不会再对Flow注解报错了。但是仅仅这样还能是不提示Flow的校验结果,还需要选择Flow executable,将Flow的cli的路径配置到这里。windows一般是C:Users用户名AppDataRoamingnpmflow.cmd,mac一般是usr/local/bin/flow。这样Webstorm就能报出Flow的校验错误了。



和vscode集成


直接安装vscode-flow-ide或者Flow-Language-Support插件即可。

以上就是这一期的全部内容,下一期会着重介绍Flow的注解使用。

以上就是:Flow简易教程——安装篇 的全部内容。

本站部分内容来源于互联网和用户投稿,如有侵权请联系我们删除,谢谢。
Email:[email protected]


0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论