优化又臭又长维护噩梦的JavaScript老项目

2022-08-24 14:46:34 浏览数 (1)

Flow:Facebook 的 JavaScript 静态类型检查器

记某年的一次团队分享,主要目的:优化又臭又长维护噩梦的JavaScript老项目

JavaScript写起来,行云流水、挥洒自如、无拘无束、笔走龙蛇、为所欲为

金主粑粑,每天抓狂,小修小补的hotfix从未停止脆弱的代码经不住半点风浪

Flow是JavaScript代码的静态类型检查器。 它可以帮助您提高工作效率。 让您的代码更快,更智能,更自信,更大规模

Flow通过静态类型注释检查代码是否存在错误。 这些类型允许您告诉Flow您希望代码如何工作,Flow将确保它以这种方式工作。

1. 从demo开始认识flow

2. 安装,配置

3. flow总结及使用

前言

我们知道react源码现在还是采用flow js的方式,下图截取一小段react Fiber源码,先混个脸熟

代码语言:javascript复制
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */
import type {ReactElement} from 'shared/ReactElementType';
import type {ReactFragment, ReactPortal, ReactScope} from 'shared/ReactTypes';
import type {Fiber} from './ReactInternalTypes';
import type {RootTag} from './ReactRootTags';
import type {WorkTag} from './ReactWorkTags';
import type {TypeOfMode} from './ReactTypeOfMode';
import type {Lanes} from './ReactFiberLane.new';
import type {SuspenseInstance} from './ReactFiberHostConfig';
import type {OffscreenProps} from './ReactFiberOffscreenComponent';

1. 从demo开始认识flow

1.1 出入参静态类型注释
代码语言:javascript复制
// @flow
function square(n: number): number {
  return n * n;
}

square("2"); // Error!

报错信息:

Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ common/globFile.js:26:8

Cannot call square with '2' bound to n because string [1] is incompatible with number [2].

1.2.运算结果类型检查

因为Flow很好地理解JavaScript,所以它不需要很多这些类型。 你应该只需要做很少的工作来描述你的Flow代码,它将推断其余部分。 在很多时候,Flow可以完全理解您的代码而不需要任何类型

代码语言:javascript复制
// @flow
function square(n) {
  return n * n; // Error!
}

square("2");

报错信息: Cannot perform arithmetic operation because string [1] is not a number.

2. 安装

2.1 安装编译器

官方推荐babelflow-remove-types

代码语言:javascript复制
npm install --save-dev @babel/cli @babel/preset-flow

项目增加babel.config.js文件

代码语言:javascript复制
module.exports = function() {
  return {
    presets: [
      "@babel/preset-flow"
    ]
  }
}

package.json中添加scripts

代码语言:javascript复制
{
  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/preset-flow": "^7.0.0",
  },
  "scripts": {
    "build": "babel src/ -d lib/",
    "prepublish": "npm run build"
  }
}
2.2 安装flow
代码语言:javascript复制
npm install --save-dev flow-bin

package.json中添加scripts

代码语言:javascript复制
{
  "devDependencies": {
    "flow-bin": "^0.99.0"
  },
  "scripts": {
    "flow": "flow"
  }
}

生成flowconfig配置文件

代码语言:javascript复制
npm run flow init

运行flow

代码语言:javascript复制
npm run flow

3. flow总结及使用

  • 3.1 使用flow init初始化项目
  • 3.2 使用flow启动Flow后台进程flow status
  • 3.3 使用// @flow确定Flow将监视哪些文件
  • 3.4 编写flow代码
  • 3.5 检查代码是否存在类型错误
  • 3.6 如何在代码中添加类型注释
3.1 使用 flow init 初始化项目

生成类似INI格式,项目.flowconfig配置文件

3.1.1 .flowconfig由6个部分组成

代码语言:javascript复制
; 忽略匹配文件
[ignore]
<PROJECT_ROOT>/__tests__/.*
<PROJECT_ROOT>/lib/.*

; 包含指定的文件或目录
[include]
<PROJECT_ROOT>/src/.*

; 在类型检查代码时包含指定的库定义
[libs]

; lint
[lints]
all=warn
untyped-type-import=error
sketchy-null-bool=off

; 选项
[options]
all=true
esproposal.decorators=ignore
experimental.const_params=true
module.file_ext=.bar
module.use_strict=true

; 严格
[strict]
nonstrict-import
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import


; none
; 在声明模式下,代码没有进行类型检查,会检查文件内容
[declarations]
<PROJECT_ROOT>/third_party/.*

; 不检查文件内容,不匹配指定正则表达式的类型文件,丢弃类型并将模块视为任何模块
[untyped]
<PROJECT_ROOT>/third_party/.*

; 指定flow使用的版本
[version]
0.98.1

3.1.2 # or ; or

0 人点赞