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

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

panda_program
November 09, 2021

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

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)

    View full-size slide

  2. 2
    © 2012-2021 BASE, Inc.
    自己紹介

    View full-size slide

  3. 3
    © 2012-2021 BASE, Inc.
    自己紹介
    プログラミングをするパンダ(@Panda_Program)
    所属
     BASE株式会社(2021年5月入社)
     Product Dev Division / Owners Experience Frontend Team
    業務内容
     新規機能開発、DX向上のための改善、
     社内用UIコンポーネント集のメンテナンスなど。
    #tech_stand
    @Panda_Program

    View full-size slide

  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

    View full-size slide

  5. 5
    © 2012-2021 BASE, Inc.
    BASE, Inc.の紹介

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  8. 8
    © 2012-2021 BASE, Inc.
    TypeScript Compiler API で
    Storybook の
    コンポーネントを置換した話

    View full-size slide

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

    JS のメタプログラミング用のツールとそのユースケース
    - jscodeshift を中心に(7分)
    まとめと反省とその次の話(1分)
    2
    3
    #tech_stand
    @Panda_Program

    View full-size slide

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

    ● 作成したスクリプトをコンポーネントに適用
    ● import 文の書き換えを紹介します
    ● メタプロのコードと処理の流れ
    #tech_stand
    @Panda_Program

    View full-size slide

  11. 11
    © 2012-2021 BASE, Inc.
    前提

    半年前、Storybook は v5 で storiesOf で書かれていた

    CSF(Component Story Format)に書き換えて v6 にしたい

    コンポーネント数のファイル数は40ほどだった。人海戦術は使いたくない

    TypeScript Compiler API(以下、Compiler API)でメタプログラミングをした
    #tech_stand
    @Panda_Program

    View full-size slide

  12. 12
    © 2012-2021 BASE, Inc.
    コストは「人海戦術 > ツール作成」
    https://devblog.thebase.in/entry/typescript-compiler-api-storybook
    #tech_stand
    @Panda_Program

    View full-size slide

  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

    View full-size slide

  14. 14
    © 2012-2021 BASE, Inc.
    作成したスクリプトを
    コンポーネントに適用

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  19. 19
    © 2012-2021 BASE, Inc.
    import 文の書き換えを紹介します
    変換前
    変換後
    #tech_stand
    @Panda_Program

    View full-size slide

  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

    View full-size slide

  21. 21
    © 2012-2021 BASE, Inc.
    メタプロのコードと
    処理の流れ

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

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

    View full-size slide

  26. 26
    © 2012-2021 BASE, Inc.
    メタプロのコードと処理の流れ
    5. ファイルとして出力する
    #tech_stand
    @Panda_Program

    View full-size slide

  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

    View full-size slide

  28. 28
    © 2012-2021 BASE, Inc.
    JS のメタプログラミング用の
    ツールとそのユースケース
    - jscodeshift を中心に

    View full-size slide

  29. 29
    © 2012-2021 BASE, Inc.
    今日お話しすること
    JS のメタプログラミング用のツールとそのユースケース
    - jscodeshift を中心に
    2
    ● 記事のTwitterでの反響
    ● コンポーネントに適用してみた
    ● Compiler API と jscodeshift のコードを比較する
    ● 比較まとめ
    ● JS のメタプロのツールについてさらに調べてみた
    ● メタプロのツールまとめ
    #tech_stand
    @Panda_Program

    View full-size slide

  30. 30
    © 2012-2021 BASE, Inc.
    記事のTwitterでの反響

    View full-size slide

  31. 31
    © 2012-2021 BASE, Inc.
    azu さん
    Babel や jscodeshift や Semgrep 👀
    https://twitter.com/azu_re/status/1438385998929428482
    #tech_stand
    @Panda_Program

    View full-size slide

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

    View full-size slide

  33. 33
    © 2012-2021 BASE, Inc.
    公式 codemod ?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    コンポーネント名、Decorators や Parameters を抽出してメタ情報を作成

    add の数だけ Story を作成

    add の第二引数(コンポーネント)には手を加えない
    #tech_stand
    @Panda_Program

    View full-size slide

  43. 43
    © 2012-2021 BASE, Inc.
    コードリーディング
    #tech_stand
    @Panda_Program
    Compiler API で実装したのと
    同じ処理は jscodeshift で
    どのように書くのだろう🤔

    View full-size slide

  44. 44
    © 2012-2021 BASE, Inc.
    Compiler API と
    jscodeshift の
    コードを比較する

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. 50
    © 2012-2021 BASE, Inc.
    比較3: export 文の作成
    変数 key に Story(変数名)、
    変数 val に () => { return { ... } }(即時関数)が格納されているとする
    #tech_stand
    @Panda_Program

    View full-size slide

  51. 51
    © 2012-2021 BASE, Inc.
    比較まとめ

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  55. 55
    © 2012-2021 BASE, Inc.
    JS のメタプロのツールについてさらに調べてみた
    https://dive-into-ast.netlify.app/47
    #tech_stand
    @Panda_Program

    View full-size slide

  56. 56
    © 2012-2021 BASE, Inc.
    JS のメタプロのツールについてさらに調べてみた
    Semgrep は指定したパターンにマッチしたものを
    抜き出して、別のものに置き換えていくイメージ
    AST の操作というより、「文字列置換 + α」の
    要件ならこちらのツールが適している感じがする
    Semgrep
    https://semgrep.dev/
    https://efcl.info/2020/12/04/semgrep/
    #tech_stand
    @Panda_Program

    View full-size slide

  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

    View full-size slide

  58. 58
    © 2012-2021 BASE, Inc.
    メタプロのツールまとめ

    View full-size slide

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

    View full-size slide

  60. 60
    © 2012-2021 BASE, Inc.
    まとめと反省と
    その次の話

    View full-size slide

  61. 61
    © 2012-2021 BASE, Inc.
    今日お話しすること
    まとめと反省とその次の話
    3
    ● 反省点
    ● Next Action(次の話)
    ● まとめ
    #tech_stand
    @Panda_Program

    View full-size slide

  62. 62
    © 2012-2021 BASE, Inc.
    反省点

    View full-size slide

  63. 63
    © 2012-2021 BASE, Inc.
    反省点
    Compiler API のコードを書きながら、
    「このコードのメンテナンスはできない」
    「一度きりの書き捨てスクリプトだ」と
    感じていたので、やっぱりやりすぎだったかなと
    思った
    解の質がイシューの質に見合っていない
    オーバーエンジニアリングとは、
    「イシューの質に対して解の質が高すぎる」こと
    『イシューからはじめよ』(安宅和人著、 EIJI PRESS社) p.25 図を元に改変
    #tech_stand
    @Panda_Program

    View full-size slide

  64. 64
    © 2012-2021 BASE, Inc.
    反省点
    実行の前に調べ尽くそう。
    人の書いたコード(ツール)を使うことで
    時間・労力を節約できる。
    そもそも公式で codemod が用意されている
    「ソフトウェアの梃子(レバレッジ)を
    有効に活用する」
    (『UNIXという考え方』の定理6)
    #tech_stand
    @Panda_Program

    View full-size slide

  65. 65
    © 2012-2021 BASE, Inc.
    よかった点
    stand.fm さんの TECH STAND の
    TS 回に誘っていただけたのでよかった
    人間万事塞翁が馬
    #tech_stand
    @Panda_Program

    View full-size slide

  66. 66
    © 2012-2021 BASE, Inc.
    Next Action
    (次の話)

    View full-size slide

  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

    View full-size slide

  68. 68
    © 2012-2021 BASE, Inc.
    Next Action(次の話)
    例1: title が不要になる
    #tech_stand
    @Panda_Program

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  72. 72
    © 2012-2021 BASE, Inc.
    まとめ

    View full-size slide

  73. 73
    © 2012-2021 BASE, Inc.
    まとめ
    ● 発信をすると逆に色々教えて貰える
    ● JS のメタプロツールはユースケースに応じて使い分ける
    ● メタプログラミングは面白い
    #tech_stand
    @Panda_Program

    View full-size slide

  74. 74
    © 2012-2021 BASE, Inc.
    ご静聴
    ありがとうございました

    View full-size slide