Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScript Compiler API で Storybook を置換した話とその次の話

B385cc78f14497199695b0daf8cd73b9?s=47 panda_program
November 09, 2021

TypeScript Compiler API で Storybook を置換した話とその次の話

B385cc78f14497199695b0daf8cd73b9?s=128

panda_program

November 09, 2021
Tweet

More Decks by panda_program

Other Decks in Technology

Transcript

  1. 1 © 2012-2021 BASE, Inc. TypeScript Compiler API で Storybook

    を置換した話と その次の話 TECH STAND #6 TypeScript プログラミングをするパンダ (@Panda_Program)
  2. 2 © 2012-2021 BASE, Inc. 自己紹介

  3. 3 © 2012-2021 BASE, Inc. 自己紹介 プログラミングをするパンダ(@Panda_Program) 所属  BASE株式会社(2021年5月入社)  Product

    Dev Division / Owners Experience Frontend Team 業務内容  新規機能開発、DX向上のための改善、  社内用UIコンポーネント集のメンテナンスなど。 #tech_stand @Panda_Program
  4. 4 © 2012-2021 BASE, Inc. 自己紹介 プログラミングをするパンダ(@Panda_Program) 趣味  Next.js を使った

    Web サイトの個人開発  最近は note の記事を PDF 化 するツールを作った。  note PDFy  https://note-pdfy.panda-program.com/ #tech_stand @Panda_Program
  5. 5 © 2012-2021 BASE, Inc. BASE, Inc.の紹介

  6. 6 © 2012-2021 BASE, Inc. ネットショップ作成サービス「BASE」 #tech_stand @Panda_Program

  7. 7 © 2012-2021 BASE, Inc. 今日お話しすること

  8. 8 © 2012-2021 BASE, Inc. TypeScript Compiler API で Storybook

    の コンポーネントを置換した話
  9. 9 © 2012-2021 BASE, Inc. 今日お話しすること TypeScript Compiler API で

    Storybook の コンポーネントを置換した話(7分) 1 JS のメタプログラミング用のツールとそのユースケース - jscodeshift を中心に(7分) まとめと反省とその次の話(1分) 2 3 #tech_stand @Panda_Program
  10. 10 © 2012-2021 BASE, Inc. 今日お話しすること TypeScript Compiler API で

    Storybook の コンポーネントを置換した話 1 • 作成したスクリプトをコンポーネントに適用 • import 文の書き換えを紹介します • メタプロのコードと処理の流れ #tech_stand @Panda_Program
  11. 11 © 2012-2021 BASE, Inc. 前提 • 半年前、Storybook は v5

    で storiesOf で書かれていた • CSF(Component Story Format)に書き換えて v6 にしたい • コンポーネント数のファイル数は40ほどだった。人海戦術は使いたくない • TypeScript Compiler API(以下、Compiler API)でメタプログラミングをした #tech_stand @Panda_Program
  12. 12 © 2012-2021 BASE, Inc. コストは「人海戦術 > ツール作成」 https://devblog.thebase.in/entry/typescript-compiler-api-storybook #tech_stand

    @Panda_Program
  13. 13 © 2012-2021 BASE, Inc. Compiler API とは何か 「TypeScript Compiler

    API とは、TypeScript の Compiler を操作するための API です。 つまり、TS/JS のコードを解析したり、TS を JS に変換したり、コー ドの文法エラーを検出するといったコンパイラの機能を利用するための API で す」 https://devblog.thebase.in/entry/typescript-compiler-api-storybook Compiler API の機能の一部を使って、 コードを書き換えることができる (=メタプログラミングができる) #tech_stand @Panda_Program
  14. 14 © 2012-2021 BASE, Inc. 作成したスクリプトを コンポーネントに適用

  15. 15 © 2012-2021 BASE, Inc. Before #tech_stand @Panda_Program

  16. 16 © 2012-2021 BASE, Inc. After #tech_stand @Panda_Program

  17. 17 © 2012-2021 BASE, Inc. import 文の書き換えを 紹介します

  18. 18 © 2012-2021 BASE, Inc. import 文の書き換えを紹介します 今回は時間の都合上 import 文の書き換え部分だけ紹介します。

    その他の箇所の説明はブログ記事を読んでいただくか、 または GitHub レポジトリをご覧ください。 ブログ https://devblog.thebase.in/entry/typescript-compiler-api-storybook レポジトリ https://github.com/baseinc/panda-storybook-v5-to-v6 #tech_stand @Panda_Program
  19. 19 © 2012-2021 BASE, Inc. import 文の書き換えを紹介します 変換前 変換後 #tech_stand

    @Panda_Program
  20. 20 © 2012-2021 BASE, Inc. import 文の書き換えを紹介します • @storybook/vue、storybook-addon-vue-info の

    import 文を削除 • knob の text の import を削除 • README の import のパスを変更('../../values/Devices' → './README.md') 変更点 #tech_stand @Panda_Program
  21. 21 © 2012-2021 BASE, Inc. メタプロのコードと 処理の流れ

  22. 22 © 2012-2021 BASE, Inc. メタプロのコードと処理の流れ #tech_stand @Panda_Program

  23. 23 © 2012-2021 BASE, Inc. メタプロのコードと処理の流れ 1. ファイルを読み込む #tech_stand @Panda_Program

  24. 24 © 2012-2021 BASE, Inc. メタプロのコードと処理の流れ • printRecursive で再帰的に AST

    を探索する • isImportDeclaration で    import 文で条件分岐する • 配列 imports に import 文を格納する 次に imports に格納された テキストを処理をする ex. [ “import { storiesOf } from '@storybook/vue'”] 2,3. AST を解析して、import 文を配列に追加する #tech_stand @Panda_Program
  25. 25 © 2012-2021 BASE, Inc. メタプロのコードと処理の流れ • filter で不要な import

    を削除 • concat で 必要な import 追加 • join で文字列に変換 • replace で import 文を部分的に書き 換え 泥臭い処理だが、 AST をいじるより 目的達成が簡単 4. import 文を書き換える #tech_stand @Panda_Program
  26. 26 © 2012-2021 BASE, Inc. メタプロのコードと処理の流れ 5. ファイルとして出力する #tech_stand @Panda_Program

  27. 27 © 2012-2021 BASE, Inc. メタプロのコードと処理の流れ 大まかにこのような書き換えを 色々なパターンで適用する • 文字列置換

    • TypeScript AST Viewer を使ってコード 生成 ブログ記事にして公開した 「TypeScript Compiler API で40の Storybook コンポーネントを storiesOf から CSF(Component Story Format)に置換した」 https://devblog.thebase.in/entry/typescript-compiler-api-storybook #tech_stand @Panda_Program
  28. 28 © 2012-2021 BASE, Inc. JS のメタプログラミング用の ツールとそのユースケース - jscodeshift

    を中心に
  29. 29 © 2012-2021 BASE, Inc. 今日お話しすること JS のメタプログラミング用のツールとそのユースケース - jscodeshift

    を中心に 2 • 記事のTwitterでの反響 • コンポーネントに適用してみた • Compiler API と jscodeshift のコードを比較する • 比較まとめ • JS のメタプロのツールについてさらに調べてみた • メタプロのツールまとめ #tech_stand @Panda_Program
  30. 30 © 2012-2021 BASE, Inc. 記事のTwitterでの反響

  31. 31 © 2012-2021 BASE, Inc. azu さん Babel や jscodeshift

    や Semgrep 👀 https://twitter.com/azu_re/status/1438385998929428482 #tech_stand @Panda_Program
  32. 32 © 2012-2021 BASE, Inc. berlysia さん 公式 codemod 👀

    https://twitter.com/berlysia/status/1438371985294127110 #tech_stand @Panda_Program
  33. 33 © 2012-2021 BASE, Inc. 公式 codemod ?

  34. 34 © 2012-2021 BASE, Inc. 😱

  35. 35 © 2012-2021 BASE, Inc. before #tech_stand @Panda_Program

  36. 36 © 2012-2021 BASE, Inc. after #tech_stand @Panda_Program

  37. 37 © 2012-2021 BASE, Inc. before/after https://github.com/storybookjs/storybook/blob/master/lib/codemod/src/transforms/storiesof-to-csf.js #tech_stand @Panda_Program

  38. 38 © 2012-2021 BASE, Inc. 適用してみた

  39. 39 © 2012-2021 BASE, Inc. before #tech_stand @Panda_Program

  40. 40 © 2012-2021 BASE, Inc. after #tech_stand @Panda_Program

  41. 41 © 2012-2021 BASE, Inc. コードリーディング せっかくなのでコードを覗いてみた 内部では jscodeshift が使われている。

    #tech_stand @Panda_Program
  42. 42 © 2012-2021 BASE, Inc. コードリーディング せっかくなのでコードを覗いてみた 内部では jscodeshift が使われている。

    ざっくり処理内容 • コンポーネント名、Decorators や Parameters を抽出してメタ情報を作成 • add の数だけ Story を作成 • add の第二引数(コンポーネント)には手を加えない #tech_stand @Panda_Program
  43. 43 © 2012-2021 BASE, Inc. コードリーディング #tech_stand @Panda_Program Compiler API

    で実装したのと 同じ処理は jscodeshift で どのように書くのだろう🤔
  44. 44 © 2012-2021 BASE, Inc. Compiler API と jscodeshift の

    コードを比較する
  45. 45 © 2012-2021 BASE, Inc. 比較1: 探索 #tech_stand @Panda_Program

  46. 46 © 2012-2021 BASE, Inc. 比較1: 探索 #tech_stand @Panda_Program

  47. 47 © 2012-2021 BASE, Inc. 比較2: オブジェクトの作成 #tech_stand @Panda_Program

  48. 48 © 2012-2021 BASE, Inc. 比較2: オブジェクトの作成 #tech_stand @Panda_Program

  49. 49 © 2012-2021 BASE, Inc. 比較3: export 文の作成 #tech_stand @Panda_Program

  50. 50 © 2012-2021 BASE, Inc. 比較3: export 文の作成 変数 key

    に Story(変数名)、 変数 val に () => { return { ... } }(即時関数)が格納されているとする #tech_stand @Panda_Program
  51. 51 © 2012-2021 BASE, Inc. 比較まとめ

  52. 52 © 2012-2021 BASE, Inc. 比較まとめ azu さんの指摘の通り、jscodeshift の方がコード量が少ない。 結果、処理内容を辿りやすいためメンテナンスができる。

    #tech_stand @Panda_Program
  53. 53 © 2012-2021 BASE, Inc. JS のメタプロの ツールについて さらに調べてみた

  54. 54 © 2012-2021 BASE, Inc. JS のメタプロのツールについてさらに調べてみた azu さんの Dive

    into AST 様々なツール(自作、ESLint、Babel、jscodeshift)で 同じ処理をするコードの比較をしている • コードの中にある eval 関数の有無判定を正規表現やESLintで行う • console.logの置換・削除を Babel、jscodeshiftで行う https://dive-into-ast.netlify.app/ #tech_stand @Panda_Program
  55. 55 © 2012-2021 BASE, Inc. JS のメタプロのツールについてさらに調べてみた https://dive-into-ast.netlify.app/47 #tech_stand @Panda_Program

  56. 56 © 2012-2021 BASE, Inc. JS のメタプロのツールについてさらに調べてみた Semgrep は指定したパターンにマッチしたものを 抜き出して、別のものに置き換えていくイメージ

    AST の操作というより、「文字列置換 + α」の 要件ならこちらのツールが適している感じがする Semgrep https://semgrep.dev/ https://efcl.info/2020/12/04/semgrep/ #tech_stand @Panda_Program
  57. 57 © 2012-2021 BASE, Inc. JS のメタプロのツールについてさらに調べてみた Compiler API の業務での使い所は

    型の生成くらい? yml から TS の型を生成するというのをやってみたことがある 「TypeScript Compiler API で型を自動生成する」 https://zenn.dev/panda_program/articles/typescript-compiler-api 他にもこんなところで使ったよ、という話があればぜひ教えて欲しいです また、TS の graphql-codegen はどうやって型生成してるんだろう(コード追いきれなかった) #tech_stand @Panda_Program
  58. 58 © 2012-2021 BASE, Inc. メタプロのツールまとめ

  59. 59 © 2012-2021 BASE, Inc. メタプロのツールまとめ • JS / TS

    でメタプロをする際は、 要件に応じて使うツールを変えると良い • ライブラリのバージョンアップの際には 公式がマイグレーションツールを出しているかチェックする (React も codemod を出している) https://github.com/reactjs/react-codemod #tech_stand @Panda_Program
  60. 60 © 2012-2021 BASE, Inc. まとめと反省と その次の話

  61. 61 © 2012-2021 BASE, Inc. 今日お話しすること まとめと反省とその次の話 3 • 反省点

    • Next Action(次の話) • まとめ #tech_stand @Panda_Program
  62. 62 © 2012-2021 BASE, Inc. 反省点

  63. 63 © 2012-2021 BASE, Inc. 反省点 Compiler API のコードを書きながら、 「このコードのメンテナンスはできない」

    「一度きりの書き捨てスクリプトだ」と 感じていたので、やっぱりやりすぎだったかなと 思った 解の質がイシューの質に見合っていない オーバーエンジニアリングとは、 「イシューの質に対して解の質が高すぎる」こと 『イシューからはじめよ』(安宅和人著、 EIJI PRESS社) p.25 図を元に改変 #tech_stand @Panda_Program
  64. 64 © 2012-2021 BASE, Inc. 反省点 実行の前に調べ尽くそう。 人の書いたコード(ツール)を使うことで 時間・労力を節約できる。 そもそも公式で

    codemod が用意されている 「ソフトウェアの梃子(レバレッジ)を 有効に活用する」 (『UNIXという考え方』の定理6) #tech_stand @Panda_Program
  65. 65 © 2012-2021 BASE, Inc. よかった点 stand.fm さんの TECH STAND

    の TS 回に誘っていただけたのでよかった 人間万事塞翁が馬 #tech_stand @Panda_Program
  66. 66 © 2012-2021 BASE, Inc. Next Action (次の話)

  67. 67 © 2012-2021 BASE, Inc. Next Action(次の話) Storybook v6.4 から

    CSF 3.0 が導入される (2021/11/8 時点では v6.4 は beta 版) 書き方がまた変わるものの、 ボイラープレートがさらに減る https://storybook.js.org/blog/component-story-format-3-0/ もうすぐ CSF 3.0 が来る #tech_stand @Panda_Program
  68. 68 © 2012-2021 BASE, Inc. Next Action(次の話) 例1: title が不要になる

    #tech_stand @Panda_Program
  69. 69 © 2012-2021 BASE, Inc. Next Action(次の話) 例2: ストーリーをオブジェクトとして使える #tech_stand

    @Panda_Program
  70. 70 © 2012-2021 BASE, Inc. Next Action(次の話) 例3: コンポーネントのデフォルトの定義が極限までシンプルになる #tech_stand

    @Panda_Program
  71. 71 © 2012-2021 BASE, Inc. Next Action(次の話) CSF 3.0 用の

    codemod が準備されている $ npx sb@next migrate csf-2-to-3 --glob="**/*.stories.js v6.4 がリリースされたら、codemod を使ってコンポーネントを書き換えよう もし細かい修正が必要な場合は、 jscodeshift で対応する #tech_stand @Panda_Program
  72. 72 © 2012-2021 BASE, Inc. まとめ

  73. 73 © 2012-2021 BASE, Inc. まとめ • 発信をすると逆に色々教えて貰える • JS

    のメタプロツールはユースケースに応じて使い分ける • メタプログラミングは面白い #tech_stand @Panda_Program
  74. 74 © 2012-2021 BASE, Inc. ご静聴 ありがとうございました