Feedforce Developer Blog

フィードフォース開発者ブログ

Flowがエラーを表示しない、または奇妙なタイミングでエラーを表示することへの対処療法

キーボード大好き id:kogainotdan です。
社内ではハンダ付けの傍ら、フロントエンドエンジニアを拝命しています。

さて、みなさんFlowは使っていらっしゃいますか?
Facebookが主導して開発しているこの静的型検査ツールは、競合のTypeScriptに比べて強力な型推論器による厳格かつ注釈をあまり必要としない(そしてたまに理不尽な)型検査が非常に魅力的です。

ところで最近Flowを使用しているプロジェクトでこんな声が聞かれるようになりました。
例えば『エディタで編集していると、急にFlowの型エラーが報告される』とか『本来エラーになるはずのコードからエラーが報告されない』であったりです。

もしかしたらそれはバージョン0.57で導入された機能と、.flowconfigに記述された設定に関わりがあるかも知れません。

このバージョンにおいて、Flowチームはnode_modulesにあるコードに対してある評価戦略を適用することにしました。

Flow will now only check the files in node_modules/ which are direct or transitive dependencies of the non-node_modules code.

です。 CHANGELOG

これによってnode_modules以下に配置されたコードは、Flowの検査対象になっているコードから使用されていない限り、検査されない(つまり遅延検査される)ようになりました。 一方、Flowのドキュメントにはmodule.system.node.resolve_dirnameオプションについて以下のような記述があります。

module.system.node.resolve_dirname (string) By default, Flow will look in directories named node_modules for node modules. You can configure this behavior with this option

このオプションに設定されたディレクトリは、node_modulesディレクトリと同じように振る舞う、ということですね。

ひょっとするとこのオプションをWebpackのresolve.modulesオプションと併用して、レポジトリ内のあるディレクトリ(例えばsrcディレクトリ)をルートディレクトリのように設定する、ということをしているかも知れません。
そのような設定は、モジュールへのパス記述の簡略化やNODE_PATH問題の解決として、ある程度一般性のある用法と推測します(少なくとも弊社ではそのように用いています)

するとどうなるかと言うと、resolve_dirnameに設定されたディレクトリが、node_modulesのように振る舞う=遅延検査されるようになります。

この時、resolve_dirnameに設定されたディレクトリにあるファイルが、Flowの検査対象になっているコードつまりresolve_dirnameに設定されたディレクトリ以外にあるコードからimportされていない限り、型検査が遅延されることになります。

(エディタ編集中にエラーが出てくるのは、内部的にflow checkやflow check-contentsなどを呼び出して、編集中のファイルに対して正格な検査が行われているものと推測しています)

詳しい解説は https://github.com/facebook/flow/issues/5180 をご覧下さい。

弊社では、

import "./path/to/entry/point";

とだけ記述されたファイルをresolve_dirnameの外に置くことで、一時的な対処としています。

コードを追う限り、該当のコードでは明示的にresolve_dirnameを遅延検査の対象にしているようなので、これはFlowチームの意図した挙動と推測しています。
しかしこの挙動は非常に混乱を招きやすいと考えられるため、上述のIssueではFlowチームの見解を待っているというのが現状です。

それまでは上記のようなワークアラウンドで問題を繰り延べにするもの一つの手かも知れません。 以上、参考になれば幸いです。