はじめに
JavaScript/TypeScript/JSXの関数フローを描くサービスを作りました。
関数フローとは何か
function from() {
to()
}
上のプログラムには関数ノード(from)から関数ノード(to)への関数フローがあります。
このサービスは1つのファイルからすべての関数フローを抽出して図示します。
なぜ作ったか
関数フローを見たいと思ったことはありませんか?
関数フローにループ構造のあるプログラムが無限ループしていないかを調べるために手作業で関数フローを描いたことがありました。
そのようなときにJavaScriptのプログラムを構文解析して抽象構文木を出力するライブラリの存在を知りました。
Qiita記事のマークダウンでも使われている、フローチャートを図示するMermaidライブラリと組み合わせれば関数フローを描くウェブサービスを作れると思って作り始めました。
使い方
中央のファイル選択ボタンを押すかファイルをブラウザ内にドラッグすると、関数フローを図示します。
図の各ノードをクリックすると、関数フローのIN/OUTの矢印を色付けします。
図の各ノードをマウスホバーすると、関数フローのIN/OUTの詳細をポップアップ表示します。
画面右上アイコンの設定ボタンをクリックすると、設定画面で指定した名前の関数フロー(to)を非表示にできます。非表示設定の既定値が存在するので、すべての関数フローを表示したい場合は空白を設定する必要があります。
いずれにせよ使い方を説明しなくても使いやすいUIになるように工夫しました。
開発時に工夫したこと
他に開発時に工夫したことです。
関数フローの非表示
すべての関数フローを表示した図は全体の構造が見づらかったので、非表示機能を作って関数フローを絞れるようにしました。余計な関数フローを非表示にすることにより、注目したい関数フローに集中できます。
矢印のつながった先
関数フローの矢印がどこにつながっているのかが見づらかったので、クリックしたノードにつながった矢印に色付けする機能をつけました。
espreeから@babel/parserへ
espreeはESLintが使うJavaScript構文解析器です。ESLintのカスタムルールを作るときに抽象構文木を触ったことがあり慣れていたので、espreeを最初に使いました。
しかし、ライセンスが混在することとjsdelivr.comが配信するライブラリが使えないことからacornに乗り換えました。acornはespreeが基にしているJavaScriptの構文解析器です。
他の構文解析器も調べました。@typescript-eslint/parserはTypeScript-ESLintが使うTypeScriptの構文解析器です。TypeScriptは専用の構文解析器を使います。
この開発では最終的に@babel/parserを選びました。JavaScriptとTypeScriptとJSXをシームレスに構文解析できるからです。最初はJavaScriptのみを受け付ける予定でしたが、TypeScriptとJSXも受け付けます。
Jestのような一括自動テスト
開発の最終段階においてもなおアジャイル開発的な仕様変更をしていたら、ある箇所の修正が予期せぬ箇所に不具合を出し、テストが終わらない状況に陥りました。しかし、Jestのような一括自動テストで単純なものを自作することによって、終わらないテストを終わらせることができました。
特に効果が大きかったのは、影響範囲が分からない箇所を変更したときに一括自動テストに引っかかって影響範囲が分かるようになったことです。アジャイル開発的な仕様変更をするごとに、通過しなかったテストそのものが廃れたかを判定することに加え、テストを更新しなければならないことが面倒でしたが、任意のJavaScript入力という複雑さを管理してテストを終わらせるには必要だったと思います。
さいごに
ファイル分割しないプログラミングをしていたためか複雑になった1ファイルの関数フローを見たいと思ってこのサービスを作りました。
一般的にはファイル分割するプログラミングが主流なのではないかと思います。その場合は1ファイルの関数フローを見たいことはあまりないかもしれません。
ですが1ファイルが複雑になり、複雑になった1ファイルの関数フローを見たいと思うようなことがあればぜひ使ってみてください。