flowtype,对文件变化的大量依赖

flowtype, large number of dependencies on file change

在我们的应用程序中,我们使用流程进行类型检查,这一切都很好,但是似乎有大量的依赖项需要在类型检查器的每次增量传递中进行检查,一次更改在非常叶子的组件上生成以下输出:

/Users/osp/Developer/bodyfast osp@DeepThought git:(oscar/ignore-firebase-functions-from-flow*)
cat /private/tmp/flow/zSUserszSospzSDeveloperzSbodyfast.log
[2020-11-18 13:21:15.219] argv=/Users/osp/Developer/bodyfast/node_modules/flow-bin/flow-osx-v0.122.0/flow start --flowconfig-name .flowconfig --autostop --from vscode --temp-dir /tmp/flow /Users/osp/Developer/bodyfast
[2020-11-18 13:21:15.219] lazy_mode=off
[2020-11-18 13:21:15.219] arch=classic
[2020-11-18 13:21:15.219] abstract_locations=off
[2020-11-18 13:21:15.219] max_workers=16
[2020-11-18 13:21:15.245] Initializing Server (This might take some time)
[2020-11-18 13:21:15.245] executable=/Users/osp/Developer/bodyfast/node_modules/flow-bin/flow-osx-v0.122.0/flow
[2020-11-18 13:21:15.245] version=0.122.0
[2020-11-18 13:21:15.245] No saved state available
[2020-11-18 13:21:15.253] Parsing
[2020-11-18 13:21:22.481] Building package heap
[2020-11-18 13:21:22.638] Loading libraries
[2020-11-18 13:21:24.527] Resolving dependencies
[2020-11-18 13:21:25.673] Resolved requires changed
[2020-11-18 13:21:26.118] to_merge: Focused: 1126, Dependents: 0, Dependencies: 370
[2020-11-18 13:21:26.118] Calculating dependencies
[2020-11-18 13:21:26.122] Merging
[2020-11-18 13:21:40.710] Merge skipped 0 of 1496 modules
[2020-11-18 13:21:40.713] Done
[2020-11-18 13:21:40.713] Checked set: Focused: 1126, Dependents: 0, Dependencies: 370
[2020-11-18 13:21:40.714] Server is READY
[2020-11-18 13:21:40.714] Took 25.469162 seconds to initialize.
[2020-11-18 13:21:41.294] Adding new persistent connection #1
[2020-11-18 13:21:41.294] Running a serial workload
[2020-11-18 13:21:41.294] Persistent request: subscribe
[2020-11-18 13:21:41.302] Subscribing client #1 to push diagnostics
[2020-11-18 13:21:41.302] Persistent response: lspFromServer None
[2020-11-18 13:21:41.302] Client #1 opened /Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:41.302] Running a serial workload
[2020-11-18 13:21:41.302] Persistent request: lspToServer textDocument/didOpen
[2020-11-18 13:21:41.302] Persistent response: lspFromServer None
[2020-11-18 13:21:41.302] Running a serial workload
[2020-11-18 13:21:41.302] Persistent request: liveErrorsRequest file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:41.351] Persistent response: liveErrorsResponse OK (0 errors, 0 warnings) file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:52.144] Running a serial workload
[2020-11-18 13:21:52.144] Persistent request: lspToServer textDocument/codeAction
[2020-11-18 13:21:52.153] Persistent response: lspFromServer textDocument/codeAction
[2020-11-18 13:21:52.154] Running a serial workload
[2020-11-18 13:21:52.154] Persistent request: lspToServer textDocument/typeCoverage
[2020-11-18 13:21:52.163] Persistent response: lspFromServer textDocument/typeCoverage
[2020-11-18 13:21:52.746] Running a serial workload
[2020-11-18 13:21:52.746] Persistent request: lspToServer textDocument/hover
[2020-11-18 13:21:52.750] Persistent response: lspFromServer textDocument/hover
[2020-11-18 13:21:55.020] Persistent request: lspToServer textDocument/didChange
[2020-11-18 13:21:55.021] Persistent response: lspFromServer None
[2020-11-18 13:21:55.021] Running a serial workload
[2020-11-18 13:21:55.021] Persistent request: liveErrorsRequest file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:55.032] Persistent response: liveErrorsResponse OK (0 errors, 0 warnings) file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:55.250] Running a serial workload
[2020-11-18 13:21:55.250] Persistent request: lspToServer textDocument/codeAction
[2020-11-18 13:21:55.260] Persistent response: lspFromServer textDocument/codeAction
[2020-11-18 13:21:56.189] Persistent request: lspToServer textDocument/didSave
[2020-11-18 13:21:56.189] Persistent response: lspFromServer None
[2020-11-18 13:21:56.193] Running a parallel workload
[2020-11-18 13:21:56.193] Persistent request: liveErrorsRequest file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:56.203] Persistent response: liveErrorsResponse OK (0 errors, 0 warnings) file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:56.203] Running a parallel workload
[2020-11-18 13:21:56.203] Persistent request: lspToServer textDocument/typeCoverage
[2020-11-18 13:21:56.213] Persistent response: lspFromServer textDocument/typeCoverage
[2020-11-18 13:21:56.213] recheck 1 modified, 0 deleted files
[2020-11-18 13:21:56.213] modified files:
[2020-11-18 13:21:56.213] 1/1: /Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:56.213] Parsing
[2020-11-18 13:21:56.230] Resolved requires are unchanged
[2020-11-18 13:21:56.248] Re-resolving directly dependent files
[2020-11-18 13:21:56.264] Resolved requires are unchanged
[2020-11-18 13:21:56.264] Recalculating dependency graph
[2020-11-18 13:21:56.305] recheck 386 dependent files:
[2020-11-18 13:21:56.305] to_merge: Focused: 1, Dependents: 385, Dependencies: 0
[2020-11-18 13:21:56.305] Calculating dependencies
[2020-11-18 13:21:56.307] Merging
[2020-11-18 13:21:57.166] Canceling since a recheck is needed
[2020-11-18 13:21:57.166] Canceling progress 1/16
[2020-11-18 13:21:57.166] Canceling progress 2/16
[2020-11-18 13:21:57.166] Canceling progress 3/16
[2020-11-18 13:21:57.166] Canceling progress 4/16
[2020-11-18 13:21:57.166] Canceling progress 5/16
[2020-11-18 13:21:57.166] Canceling progress 6/16
[2020-11-18 13:21:57.166] Canceling progress 7/16
[2020-11-18 13:21:57.166] Canceling progress 8/16
[2020-11-18 13:21:57.166] Canceling progress 9/16
[2020-11-18 13:21:57.166] Canceling progress 10/16
[2020-11-18 13:21:57.166] Canceling progress 11/16
[2020-11-18 13:21:57.166] Canceling progress 12/16
[2020-11-18 13:21:57.166] Canceling progress 13/16
[2020-11-18 13:21:57.166] Canceling progress 14/16
[2020-11-18 13:21:57.166] Canceling progress 15/16
[2020-11-18 13:21:57.166] Canceling progress 16/16
[2020-11-18 13:21:57.168] Recheck successfully canceled. Restarting the recheck to include new file changes
[2020-11-18 13:21:57.168] recheck 1 modified, 0 deleted files
[2020-11-18 13:21:57.168] modified files:
[2020-11-18 13:21:57.168] 1/1: /Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:21:57.168] Parsing
[2020-11-18 13:21:57.195] Resolved requires are unchanged
[2020-11-18 13:21:57.195] Re-resolving directly dependent files
[2020-11-18 13:21:57.210] Resolved requires are unchanged
[2020-11-18 13:21:57.210] Recalculating dependency graph
[2020-11-18 13:21:57.245] recheck 386 dependent files:
[2020-11-18 13:21:57.245] to_merge: Focused: 1, Dependents: 385, Dependencies: 0
[2020-11-18 13:21:57.246] Calculating dependencies
[2020-11-18 13:21:57.247] Merging
[2020-11-18 13:22:04.786] sending (0 errors) and (warnings from 1 files) to 1 subscribed clients (of 1 total)
[2020-11-18 13:22:05.040] sending (0 errors) and (warnings from 1 files) to 1 subscribed clients (of 1 total)
[2020-11-18 13:22:05.307] sending (0 errors) and (warnings from 1 files) to 1 subscribed clients (of 1 total)
[2020-11-18 13:22:05.905] sending (0 errors) and (warnings from 1 files) to 1 subscribed clients (of 1 total)
[2020-11-18 13:22:07.968] Merge skipped 0 of 386 modules
[2020-11-18 13:22:07.969] Done
[2020-11-18 13:22:07.970] Checked set: Focused: 1126, Dependents: 0, Dependencies: 370
[2020-11-18 13:22:07.976] sending (0 errors) and (warnings from 37 files) to 1 subscribed clients (of 1 total)
[2020-11-18 13:22:07.976] Running a serial workload
[2020-11-18 13:22:07.976] Persistent request: liveErrorsRequest file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js
[2020-11-18 13:22:08.043] Persistent response: liveErrorsResponse OK (0 errors, 0 warnings) file:///Users/osp/Developer/bodyfast/src/Containers/SettingsMealsScene.js

您可以看到我更改了 SettingsMealsScene,但这会重新检查 386(!) 个文件,我需要 5 - 6 次才能看到任何类型错误。

有没有看到生成的依赖树?难道我们的流量配置有什么问题吗?

我们的.flowconfig.js:

[ignore]
.*/node_modules/react-native-keyboard-aware-scroll-view/.*
.*/node_modules/react-native-fbsdk/.*
.*/node_modules/@react-native-community/picker.*
.*/node_modules/@react-native-community/slider.*
# remove when flow is updated. Currently leads to "Cannot assign rest to restState because rest [1] is incompatible with State [2]."
.*/node_modules/redux-persist/lib/persistReducer.js.flow
.*/node_modules/recompose/dist/Recompose.cjs.js.flow
.*/firebase/**

; We fork some components by platform
.*/*[.]android.js

; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/

; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*

; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/warning')
node_modules/warning/.*

; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js

[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
.*/node_modules/react-native-confetti-cannon/.*
.*/node_modules/react-native-linear-gradient/.*

[libs]
node_modules/react-native/interface.js
node_modules/react-native/flow/
flow/libs

[options]
emoji=true

esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable
module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js
module.system.node.allow_root_relative=true
munge_underscores=true
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/'
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
module.name_mapper.extension='svg' -> '<PROJECT_ROOT>/flow/SVGFlowStub.js'

suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState

suppress_comment=\(.\|\n\)*\$FlowFixMe\($\|[^(]\|(\(<VERSION>\)? *\(site=[a-z,_]*react_native\(_ios\)?_\(oss\|fb\)[a-z,_]*\)?)\)
suppress_comment=\(.\|\n\)*\$FlowIssue\((\(<VERSION>\)? *\(site=[a-z,_]*react_native\(_ios\)?_\(oss\|fb\)[a-z,_]*\)?)\)?:? #[0-9]+
suppress_comment=\(.\|\n\)*\$FlowExpectedError

[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error

[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import

[version]
^0.122.0

您应该尝试将 Flow 升级到 v0.133 并切换到 Types-First architecture, or enable it on earlier releases. The rechecks have considerably improved, as explained, since all module exports are now annotated instead of being infered. There is a codemod availble 以在大型代码库上注释导出:

yarn flow codemod --help

如果您仍然关心性能,您可能想要探查昂贵的循环、模块之间共享并从中重新导出的导出类型,随着新模块的解析不断完善。我根据过去的实际经验提供这个,尽管我不知道它在较新版本中的相关性如何:可视化导致重新检查缓慢的模块的依赖关系图,并尝试通过将相关的 code/types 移动到独立的来解决周期问题模块:

yarn flow cycle --strip-root --types path/to/module.js | dot -Tpng > cycle.png