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

ご清聴ありがとうございました