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
条件:
.flowconfig
flow-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