JavaScript ASTを使ったツール(自作、ESLint、Babel、jscodeshift)を実装する話
Dive into ASTというJavaScriptのASTを使ったツールの作り方を見ていく話を書きました。 自作の正規表現、ASTチェックツール、ESLint、Babel、jscodeshiftでそれぞれ動くツールを実装してるので、リポジトリにまとめてあります。
スライドではCode Surferを使ってASTや書き方をインタラクティブに解説しています。
- スライド: Dive into AST
- リポジトリ: azu/dive-into-ast:
JavaScriptを中心にしたAST(Abstract Syntax Tree)を使ったツールの作り方についての資料です!
— azu (@azu_re) December 3, 2019
自作ASTツール、ESLint、Babel、jscodeshift それぞれでASTを使ったツールをどう実装していくのかを見ていけます。
スライド: https://t.co/yht9cGB0Hs
リポジトリ: https://t.co/Kxk9bur7TF pic.twitter.com/N2oEEYBUWq
背景
以前にもASTについては記事やスライドを書いています。 ASTとは何?という話はこの辺と大きくは変わってないです。
JSConf.JPでASTの野外ライブコーディングをしていたt_wadaさんとASTについて教えるときにどこにフォーカスして話すのがいいのかという話をしてました。
t_wadaさんとASTについて教えるときどこまで話すかが難しいという話したけど、
— azu (@azu_re) November 30, 2019
特定の領域(ESLint、Babel pluginみたいな感じ)に掘るか
広く浅くやるか
のどっちかという話になった。
広く浅くは前に書いてたので、特定の領域で掘るかーhttps://t.co/VcHt1Wtafjhttps://t.co/jgs23lrx0e#jsconfjp
ASTの触りの話は以前もやってたので、もっとツールとか狭い領域にフォーカスしたものをやってみるかということで作ってみました。
ASTを触るツールを書いてみると、普段のプログラミングであまりしないパターンも結構行うので色々学びがあると思います。 DOMもツリーなのでASTと似た構造ですが(実際にTreeWalkerとかTraverseするものもある)、ウェブサイトを作るのとツールを作るのはやっぱり違う感じはします。
スライドでも書いてましたが、ASTを扱うパーサなどのツールはかなり充実してきているので、最近ではかなり簡単にASTに触れます。 ASTを使ってちょっとした自動化をするようなツールを作ってみると面白いのかもしれません。
自然言語を扱うtextlintもMarkdownなどのASTを扱ってルールを書きます。
npx create-textlint-rule example
でルールを書き始められるので、文章に興味がある人はこの辺を見てみるのもいいかもしれません。
- textlint-scripts 3リリース、TypeScriptでtextlintのルールを作成できるようになりました | Web Scratch
- Creating Rules · textlint
その他
ASTを吐くパーサの作り方は誰かがやってください。
ASTを扱うツールのテストはスナップショットテストをするのがいいと思います。 大体がコード(AST)を入力にしてコード(AST)を出力とかになるのでスナップショットテストが向いていることが多いです。 テストケースをファイルを追加するだけで増やせてカバー率が上げやすくなります。
たとえばPrettierのテストはほとんどがスナップショットテストです。
パーサとかはテストファースト的にやると進みやすい気がします。 考えすぎるとScanner書くまでに時間がかかるので、テストケースを集めるところからやるのがいい気がします。 無理な構造になってくるとそこまでの実装は捨てたくなって捨てるかもしれませんが、テストケースは残ります。
sentence-splitterはそんな感じで書いてた気がします。
入力になるテストケースはあればあるほど安心はできるので(CIじゃなくて手動でいい)、コーパス的に集めたものを使うこともあります。 textlintルールを書くときは次のようなコーパスを使ったりしてます。
ASTを使ったライブラリとして使うようなValidatorを実装するときは、実データを使ってIntegrationテストすると安心できます。 データベースから対象となるものを全部ダンプしてきて、手動でValidateを通して意図に反した結果がないかを検証していくとか。
次のValidationはクロールした実データを使って手動で試したりしてました。
目的の形のランダムなデータを生成できるfuzzerがあるならFuzzingしてテストするのも面白いかもしれません。
特にパーサを作る場合は、許可された書き方なのにパースエラーが出るのは一番嫌がられるので、物量でカバーするのが良い気がします。 JavaScriptのコード/ASTなら、有名所のライブラリをテストケースに使うというのがよく取られる手法です(ベンチマークにもなる)。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。