yulin 2019-06-30
JavaScript是一个弱类型的解释性语言,无法在编译环节进行静态类型校验,如果想JS也具备静态类型检查功能。那就得使用到Flow,Flow由Facebook推出,官网是 https://flow.org/。Flow与微软的TypeScript有些类似,但TypeScript其实像是另一门新语言,而Flow可以理解为一个工具,象vue2、react等都是基于Flow开发,所以很有必要了解一下Flow。
安装方法:有npm和yarn两种,yarn为facebook出品,现在好象更流行一些
安装方式:全局安装 yarn global add flow-bin
安装过程:
$ yarn global add flow-bin yarn global v1.12.3 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... success Installed "[email protected]" with binaries: - flow Done in 6.32s.
安装位置:
$ yarn global bin C:\Users\Administrator\AppData\Local\Yarn\bin # 注意:npm全局安装位置是C:\Users\Administrator\AppData\Roaming\npm # 注意:请将...Yarn\bin目录添加到系统全局变量path中
cli命令说明:
$ flow --help # 查看帮助信息 # flow 命令,实际上是调用的是C:\Users\Administrator\AppData\Local\Yarn\Data\global\node_modules\flow-bin\flow-win64-v0.89.0\flow.exe,不同操作系统调用的是不同的执行文件
工作目录:切换到项目根目录,我的是F:\youshengyouse\learn-flow
配置flow: 命令是$ flow init,它会在当前目录下生成一个.flowconfig文件,内容如下
[ignore] [include] [libs] [lints] [options] [strict]
凡加Flow注释的文件,以下称flow文件,flow文件就是将// @flow或 /* @flow */加到js文件的最顶部。只有flow文件,flow进程才会在后台监视这些文件,当有类型检查时,有错误它就会报错
准备第1个js文件: 内容如下
// @flow
function square(n:number): number {
return n * n;
}
square('2')执行 flow check,报错如下:
$ flow check
Error ---------------------------------------------------------------------------- a.js:6:8
Cannot call `square` with `'2'` bound to `n` because string [1] is incompatible with number [2].
a.js:6:8
6| square('2')
^^^ [1]
References:
a.js:2:19
2| function square(n:number): number {
^^^^^^ [2]
Found 1 error将square('2')改为square(2)再flow check看下
$ flow check Found 0 errors
或者将// @flow去掉,都会提示Found 0 errors
启动: flow status
停止: flow stoop
function square(n:number): number {中的类型标注,如:number,含有这样的js文件,事实上运行起来会报错的,不论是在nodejs还是浏览器中,现在在nodejs中运行测试下
$ node a.js
F:\youshengyouse\del\a.js:2
function square(n:number): number {
^
SyntaxError: Unexpected token :
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Object.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:283:19)将两个:number去掉再测试下,不会报错。所以说flow文件是两个过程,编程时加上类型检查,最后成品代码中,得将所有的类型约束要去掉,去掉这个过程肯定不能人工操作,有相应的程序处理。目前有两个方法去掉类型注解,一是包flow-remove-types,二是在babel中去掉
安装
# 如果没有package.json文件,先生成 yarn add --dev flow-remove-types # or npm install --save-dev flow-remove-types
去类型
# 为了方便,先将a.js移到src目录下 $ yarn run flow-remove-types src/ -d dist/ yarn run v1.12.3 $ F:\youshengyouse\del\node_modules\.bin\flow-remove-types src/ -d dist/ src\a.js ↳ dist\a.js Done in 0.30s.
去类型前
// @flow
function square(n:number): number {
return n * n;
}
square(2)去类型后
//
function square(n ) {
return n * n;
}
square(2)安装
yarn add --dev babel-cli # 凡需要在命令行执行babel,得安装babel-cli yarn add --dev babel-preset-flow # 目的就是去除类型
提示: babel在没有配置时,也不认识类型,也会报错,如没有配置就转码,会报错如下
$ ./node_modules/.bin/babel src -d dist
SyntaxError: src/a.js: Unexpected token, expected , (2:17)
1 | // @flow
> 2 | function square(n:number): number {
| ^
3 | return n * n;
4 | }
5 |现在配置预置看下,新建配置文件 .babelrc,内容如下
{
"presets": ["flow"]
}再执行
$ ./node_modules/.bin/babel src -d dist src\a.js -> dist\a.js
没有报错,打开dist/a.js看下,内容如下
function square(n) {
return n * n;
}
square(2);类型约束全部去掉了。查看flow预置源码,其实它只是包装了@babel/plugin-transform-flow-strip-types这个插件而已,干活的是这个插件,打开源码,其实比较好理解,就是删除// @flow及类型
上面使用flow check来进行类型检查,不是很方便,我想babel的插件来进行类型检查,并在编辑器如vs code中自动检查,这样效率就会高很多,这就要用到插件babel-plugin-typecheck,它与预置flow的功能完全不一样,babel-plugin-typecheck是检查代码中的类型是否有错,babel-preset-flow是负责删除类型的,这样js代码在执行时就好象从来没有加过类型一样。
在vs code中搜索flow,发现有vscode-flow-ide、Flow-Language-Support两个插件,在这里以vscode-flow-ide为例
先安装vscode-flow-ide
条件:
.flowconfigflow-bin配置(默认就行)vs code左下角管理/设置/User Settings/Extensions/Flow-IDE Configurations(只有启用后才能配置,否则找不到这项),下面是文字版,实际上在面板中就可以设置
重启vs Code,就会发现可以报错了,现在可以去掉顶部的// @flow及传递不合要求的参数测试下。
如果在problem窗口有错误,[ts]'types' can only be used in a .ts file. 8010,请在扩展中找到typescript,找到"javascript.validate.enable": false