codemodとうまく付き合うには
by
did0es
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
codemodと うまく付き合うには 2024/01/19 Hirai Shuta
Slide 2
Slide 2 text
Hirai Shuta(did0es) Software engineer at CyberAgent, Inc. Main organizer at Meguro.es Maintainer for pmndrs/three-stdlib X : https://x.com/did0es GitHub : https://github.com/shuta13
Slide 3
Slide 3 text
目次 1. 背景 2. ASTとjscodeshift 3. codemodのpros/cons 4. consに対処するための工夫 5. まとめ
Slide 4
Slide 4 text
1. 背景
Slide 5
Slide 5 text
これの内容を元に、運用目線でcodemodについてお話します codemod zenn [検索]
Slide 6
Slide 6 text
これの内容を元に、運用目線でcodemodについてお話します
Slide 7
Slide 7 text
対象① ・Deprecatedな文法の修正 ・JSDocでdeprecatedとしているものの削除と置換 ・300ファイル以上のjsx?|tsx?が対象 ・気づいた人が手でRecommendedな文法に直していた ・が、差分でコンフリクトしまくり ・自動化して、一撃で全部直したい
Slide 8
Slide 8 text
対象② ・コード生成した成果物の名前の衝突解消 ・Plop.jsでコード生成する際のHandlebarsの記述をミスった ・a/b/c.ts が c.ts として扱われた(親ディレクトリの情報が抜け落ちた) ・↑に気づかず運用、ある日 CI が落ちて気づく ・すべてのファイルの命名を一定のルールをもとに変更する ・所属していたプロジェクトは60ファイルだったが... ・自動化して、一撃で全部直したい
Slide 9
Slide 9 text
解決案 ・正規表現 ・手っ取り早い ・複雑な表現は🤯 ・高度正規表現人材を雇用することが必要 ・AST ・プログラマブルに置換できる ・キャッチアップコスト😇 ・周りにASTを広めることが必要
Slide 10
Slide 10 text
2. jscodeshiftとAST
Slide 11
Slide 11 text
jscodeshift https://github.com/facebook/jscodeshift ・JavaScriptのASTのラッパー + 置換用CLI ・ASTの操作にはRecast(後述)が使われている ・Meta製 ・一瞬開発止まったが再開した様子
Slide 12
Slide 12 text
Recast ・JavaScript ASTパーサー ・以下を順に行う ・ソースコードを AST に変換 ・AST を探索・置換 ・AST をソースコードに変換
Slide 13
Slide 13 text
💡JavaScript ASTクイズ💡
Slide 14
Slide 14 text
これ何のJS AST?
Slide 15
Slide 15 text
Acorn
Slide 16
Slide 16 text
これ何のJS AST?
Slide 17
Slide 17 text
Esprima
Slide 18
Slide 18 text
Esprima ・Recastが使用しているJavaScript AST ・ふんわり雰囲気だけ掴んでください ・ちなみにJavaScriptのASTを辿っていくと これか前述のAcornのどれかにたどり着く(はず)
Slide 19
Slide 19 text
3. codemodのpros/cons
Slide 20
Slide 20 text
pros:コマンド一発 ・codemodはCLI でオプションを組み合わせて使う想定 ・対話型と違って、コピって人に渡しやすい (なんかフロント周辺のCLIは対話型が多い)
Slide 21
Slide 21 text
pros:修正過程がコードで残る ・人に手順を伝えやすい ・コマンド化しやすい ・再利用しやすい
Slide 22
Slide 22 text
pros:(比較的)楽しい ・心を無にして、grepした経験ありませんか? ・コード書いてるな〜という気持ちになれる ・機械的な作業感がなくなる ・不思議とリファクタリングタスクの意欲が出る
Slide 23
Slide 23 text
cons:属人化 ・別にcodemodにだけ当てはまる話ではないが... ・codemodかけます!ASTをゴリゴリtraverseしてます!という人は あまり(僕の周りには)いなかった ・周りにAST分かる人がいるならASTはかなり強力 ・いないなら啓蒙するか、諦めて正規表現100本ノック
Slide 24
Slide 24 text
cons:1回書いたら終わり ・いわゆる「動けばいい」で書かれてしまいがち ・こういうモチベで書かれたコードは大抵本人も読めなくなる ・script系の宿命かもしれない ・が、ある日再び必要となるときが来るので、残した(はず) ・再利用しないならそもそも共有しない
Slide 25
Slide 25 text
cons:デバッグ難易度が若干高い ・ASTをtraverseするため「今何回目のループ?」になりがち ・console.logを仕込んで粘る ・(後述の)ExplorerでASTを見る
Slide 26
Slide 26 text
4. consに対処するための工夫
Slide 27
Slide 27 text
工夫:codemod周辺技術を周りに広める 対象の課題:属人化 ・一般論ではありますが、勉強会しましょう! ・周りのcodemodやASTへのリテラシーを上げる ・jscodeshiftのdocsを輪読、写経など ・ちなみに、実装した後にDesign Doc書いたが読まれなかった😭 ・多分もっと受動的にASTを知れるほうがいい
Slide 28
Slide 28 text
工夫:jscodeshiftのtestUtilsでテスト書きまくる 対象の課題:1回書いたらおわり
Slide 29
Slide 29 text
jestでも書けるが... ・codemodはテストケース増えがち→tableがモリモリ増えて差分がつらい
Slide 30
Slide 30 text
テストケースの入出力の分離 ・testUtilsでファイルに切り出せる ・jscodeshiftの内部でも同様のテストが行われている
Slide 31
Slide 31 text
AST Explorerを使う 対象の課題:デバッグ難易度が若干高い
Slide 32
Slide 32 text
AST Parserを選ぶ 選択すると貼り付けたJSのASTが見れる + インスペクトできる
Slide 33
Slide 33 text
jscodeshiftのシミュレート AST Explorerでjscodeshiftを走らせて変換結果を見れる
Slide 34
Slide 34 text
これでも無理なら心を込めてconsole.log❤
Slide 35
Slide 35 text
細かい目のTips
Slide 36
Slide 36 text
Tips①:$から始まる変数 ・jQueryではない ・@next/codemodのコードにちらほらある ・jscodeshiftのインスタンスを格納する変数 ・jscodeshiftから取り出した値は $ なし ・何が良い? ・TSなくてもある程度戦える
Slide 37
Slide 37 text
Tips②:early return ・IOの回数は減らしたい ・jscodeshiftなら、各transformerごとに1回までが理想 ・returnすると変換のプロセスが終わってしまう ・ASTのtypeを見て、その後の処理を続けるかどうか判断する場面 ・ネストの数減らしたいのでearly returnしたくなる ・なるべく jscodeshift.~~~.forEach 内に留める ・即時関数などで1層覆っておく
Slide 38
Slide 38 text
Tips②:early return
Slide 39
Slide 39 text
5. まとめ
Slide 40
Slide 40 text
今までの所感と今後 ・対象①のケースのcodemodは作ってから3年くらい経つが運用されている ・周囲にASTが分かる人がいたのが良かった ・対象②のケースは僕が離脱した時点で捨てられた(多分) ・ASTにかかわらず使う技術は周りに広める そこまでがセット ・今後 ・腐らないcodemodを書く ・ESLintのFlat ConfigやTailwindCSSのclassName変換をやってみる
Slide 41
Slide 41 text
ご清聴ありがとうございました