ReactのソースコードをVSCodeで快適に読む
背景
ちょっと個人的な興味からReactのソースコードを読みたいと思っていたのですが、案外環境を整えるのが面倒だった&情報が少なかったので簡単に手順をまとめます。
結論
- 2023年8月現在、ReactのソースコードはFlowという形式で書かれている
- FlowはVSCodeでそのまま開いてもうまく補完等が効かないケースがある
- Metaが出している公式のFlow用のVSCodeプラグインを入れると幸せになれる
前提
前提知識をつらつら書きます。手っ取り早く手順だけ知りたい方は「手順」の箇所まで飛ばしてください。
ReactのソースコードはFlowで書かれている
執筆時点において、ReactのソースコードはFlowという型アノテーションで記述されています。
筆者はJavaScript自体にそこまで詳しくなくて知らなかったのですが、これはTypeScriptにインスパイヤを受けた、Meta独自のJavaScriptに対する型アノテーションライブラリになっているようです。[1]
下記はReactのソースコードからのそのままの抜粋ですが、パッと見はTypeScriptの構文に結構近しい雰囲気です。
let legacyErrorBoundariesThatAlreadyFailed: Set<mixed> | null = null;
// Only used when enableProfilerNestedUpdateScheduledHook is true;
// to track which root is currently committing layout effects.
let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null;
let rootDoesHavePassiveEffects: boolean = false;
let rootWithPendingPassiveEffects: FiberRoot | null = null;
let pendingPassiveEffectsLanes: Lanes = NoLanes;
let pendingPassiveProfilerEffects: Array<Fiber> = [];
let pendingPassiveEffectsRemainingLanes: Lanes = NoLanes;
let pendingPassiveTransitions: Array<Transition> | null = null;
ところが一方で、TypeScriptにはない構文も存在します。
export type LoggerEvent =
| {
+event_name: 'loaded-dev-tools',
}
| {
+event_name: 'error',
+error_message: string | null,
+error_stack: string | null,
+error_component_stack: string | null,
}
| {
+event_name: 'selected-components-tab',
}
| {
+event_name: 'selected-profiler-tab',
}
field名の先頭に +
のシンボルが付いていますが、FlowではこれでfieldがreadOnlyであることをannotateできるようです。
VSCodeは、JavaScriptとTypeScriptに対してはビルトインでLanguage Serverを含めてくれていますが、残念ながらFlowに対するLanguage Serverはありません。
従って、ReactのソースコードをそのままVSCodeで読み込むとエラーの嵐になるはずです😇 [2]
Flowに対応したVSCodeプラグイン
Flowで書かれたJavaScriptに対してもインテリセンスを効かせるために、MetaがVSCode向けのFlowプラグインを提供してくれています。
ありがたくこれを使わせてもらいましょう。
手順
具体的な手順です。
1. ReactのリポジトリをClone
reactのリポジトリをローカルに落とします。事故らないようにforkしておくといいと思います。
2. 依存をinstall
cloneしたら依存をinstallします。
reactのリポジトリの場合はpackage.jsonにflowの設定スクリプトを用意してくれているので、これを叩きます。
$ yarn install
# flowの設定
$ yarn run flow dom-node
上記手順後に node_modules/.bin/flow
が生成されますが、plugin側がこれを使います。
3. VSCode側の設定
プラグインをインストールします。
インストール後に、settings.jsonに次のような設定を追加。(その他の細かい設定はこの辺りを参照)
{
"flow.pathToFlow": "${workspaceFolder}/node_modules/.bin/flow",
"flow.useNPMPackagedFlow": true,
"javascript.validate.enable": false
}
"javascript.validate.enable": false
を追加しないと、VSCodeが普通のJavaScriptに対して出力するアラートを出力してしまうので必要です。[3]
4. 動作確認
上記手順でFlowのコードに対してもコードジャンプ等のエディタの機能が効くはずです!
まとめ
今後もReactがFlowで管理され続ける限りは、コードを快適に読むには上記の手順を踏む必要がありそうです。
個人的にはReactもTypeScriptを使用してくれた方がありがたい気もするのですが、Meta的になにか事情があるのでしょうか。似たような議論が下記のスレッドでも展開されていたので、気になる人はこの辺の話を追ってみても面白いかもしれません。
-
こちらのスレッドにFlowが導入された動機として、TypeScriptではパフォーマンスが十分でないケースに適応するため、という記述がありました。 ↩︎
-
はじめのうちはFlowで書かれた.jsを無理やり.tsに拡張子を書き換えて、多少エディタからのwaringを少なくするみたいな暴挙をやったりしてました ↩︎
-
マーケットプレイスに記載されてる
or completely disable the built-in TypeScript extension for your project (see gif below):
の手順だと何故かJavaScriptのalertが出力されたままになってしまい、こっちの"javascript.validate.enable": false
の方だとうまくいきました。 ↩︎
Discussion