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

負債が溜まったレガシーフロントエンド画面を Vue.js でリプレイスした話

t0yohei
October 16, 2022

負債が溜まったレガシーフロントエンド画面を Vue.js でリプレイスした話

Vue Fes Japan Online 2022 での発表資料です。
https://vuefes.jp/2022/sessions/t0yohei

t0yohei

October 16, 2022
Tweet

More Decks by t0yohei

Other Decks in Programming

Transcript

  1. 負債が溜まった
    レガシーフロントエンド画面を
    Vue.js でリプレイスした話
    Vue Fes Japan Online 2022 - 2022/10/16

    View Slide

  2. 自己紹介
    ● とよへい ( @t0yohei )
    ● 株式会社クラウドワークス
    ○ Web エンジニア
    ● アニメとコーヒーが好き
    ● Vue.js / Ruby / PHP

    View Slide

  3. 想定する聞き手
    ● レガシーなフロントエンドに向き合っている方
    ● Vue.js での開発ノウハウに興味がある方
    ● 不思議なものがみたい方

    View Slide

  4. Midjourney

    View Slide

  5. アジェンダ
    ● なぜ Vue.js 化を実施したのか
    ● どういう作戦で進めていったか
    ● 品質管理について
    ● 難しかったこと
    ● まとめ

    View Slide

  6. なぜ Vue.js 化を実施したのか

    View Slide

  7. View Slide

  8. クラウドワークスのフロントエンドについて
    ● クラウドワークスは、10年ほど前に Rails + jQuery の構成で生まれた
    ● 新規画面は Vue.js で作成されているが、jQuery を使った古い画面がかなり残って
    いる

    View Slide

  9. クラウドワークスのフロントエンドが抱えている課題
    ● 見た目を変えたいだけなのにバックエンドの Rails をいじる必要がある
    ● フロントエンド、バックエンドの分業がしにくい
    ● jQuery を書きたくない

    View Slide

  10. これらの課題を
    Vue.js 化で解決しよう

    View Slide

  11. Vue.js 化して既存画面を
    もっと改善しやすくしよう

    View Slide

  12. どういう作戦で進めていったか

    View Slide

  13. Vue.js 化の大まかな方針
    ● 最終的には全画面を Vue.js 化したい
    ● 時間的な制約もあるので、優先順位が高いものから対応していく

    View Slide

  14. 優先順位はどうやってつけよう

    View Slide

  15. 「Vue.js 化して既存画面を
    もっと改善しやすくしよう」

    View Slide

  16. 将来的に改善したくなる可能性が
    高い画面を優先する

    View Slide

  17. ユーザーのアクセスが多い
    一般ユーザー向け画面

    View Slide

  18. 優先順位の考慮から外した観点
    ● UIの変更が頻繁に行われている画面
    ○ 特定の理由で更新されているだけ (バナー更新とか)
    ○ 単に手を入れるのが簡単

    View Slide

  19. 両方大事にした観点
    ● 対応が簡単な画面をたくさん改善
    ○ ユーザーに対するインパクト
    ● 対応が難しい画面にじっくり挑む
    ○ 長期的な改善に対するインパクト

    View Slide

  20. ひとまずの Vue.js 化を行う画面
    ● 練習用の管理画面 × 1
    ● 一般ユーザー向けの簡単な画面 × 2
    ● 一般ユーザー向けの難しい画面 × 1
    ● (これらの画面の対応が終わったら、体制を整えて Vue.js 化を継続する)

    View Slide

  21. 実装のスコープ

    View Slide

  22. 「Vue.js 化して既存画面を
    もっと改善しやすくしよう」
    という目的に注力して、色々やりすぎない

    View Slide

  23. 何をやらないか(スコープ外)
    ● CSSフレームワークを外す
    ● バックエンドに API を生やして、API 経由でデータのやりとりをする
    ● その他コストがたくさんかかりそうなことは無理にやらない

    View Slide

  24. 品質管理について

    View Slide

  25. 各種ツールと人力で品質を担保
    ● Storybook
    ○ コンポーネント毎の動作を担保
    ● VRT(Visual Regression Testing)
    ○ 見た目の確認と、置き換え途中でデグレしていないことを担保
    ● vue-test-utils
    ○ API 通信などの動作を担保
    ● 手動テスト
    ○ 統合的な動きを担保

    View Slide

  26. View Slide

  27. Storybook

    View Slide

  28. View Slide

  29. View Slide

  30. VRT
    (Visual Regression Testing)

    View Slide

  31. View Slide

  32. View Slide

  33. ● フロントエンド開発体験向上のために VRT を導入してみた
    ● crowdworks.jp のフロントエンド活動を振り返る 2021
    詳細はテックブログに

    View Slide

  34. E2E テストは不採用
    ● 負債が溜まった画面の E2E テスト、とても辛さそう
    ● 一括のリプレイスを考えていたので、メリットがそこまで多くなさそう
    ● (リプレイス全体を通して大きな問題は発生しなかったのでヨシ)

    View Slide

  35. 難しかったこと

    View Slide

  36. Rails, jQuery のコードを
    Vue.js っぽいコードに書き換える

    View Slide

  37. 具体的には
    ● 命令的 UI を宣言的 UI にする
    ● Rails, jQuery のコードを Vue.js, TypeScript のコードに書き換える
    ● バックエンド(Rails)からフロントエンド(Vue)に適切な値を引き渡す

    View Slide

  38. 例: 仕事の予算を表示する部分

    View Slide

  39. 置き換え前のコード

    View Slide

  40. 何らかの html を生成して挿入する
    ここで生成された html を挿入する

    View Slide

  41. 置き換え後のコード

    View Slide

  42. View Slide

  43. 宣言的に書く

    View Slide

  44. script setup を使って
    Vue.js と TypeScript で実装

    View Slide

  45. これいるの...?ってコードが
    埋まってる

    View Slide

  46. 具体的には
    ● A/B テストの残骸
    ● どこからも参照されてなさそうなコード
    ● 新しく作成されるデータでは付与されることがないラベル

    View Slide

  47. 実は前から壊れていた🙄

    View Slide

  48. View Slide

  49. 本体リリースに先駆けてお掃除

    View Slide

  50. とにかく機能が多い

    View Slide

  51. 中ボスが 50 人くらいいるイメージ

    View Slide

  52. 機能ごとにコンポーネントを分けてひたすら作成

    View Slide

  53. 工夫: Containar Component で統制を取りやすく
    ● style を持たない Vue コンポーネント
    ● 自身が含むプレゼンテーションコンポーネントにデータを受け渡す
    ● バックエンド API とやりとりするためのインターフェースを持つ

    View Slide

  54. style を持たない
    バックエンド API とやりとりする
    ためのインターフェース
    プレゼンテーション
    コンポーネントにデータを受け渡す

    View Slide

  55. 工夫: Layout Component でスタイル定義を分離
    ● script を持たない Vue コンポーネント
    ● slot を使ってコンポーネントを入れ込む

    View Slide

  56. slot を使って
    コンポーネントを入れ込む
    script を持たない
    Layout Component

    View Slide

  57. 共通のスタイル定義を切り出すとかもできる
    共通のスタイル定義を切り出す

    View Slide

  58. どうして...ってコードがある

    View Slide

  59. 気になるボタン(Watchlist Button)

    View Slide

  60. View Slide

  61. 修正前の実装

    View Slide

  62. watchlist のデータ(json)を非同期で一
    括で取ってくる
    取得したデータ(json)に html が含まれ
    ているので、id が一致した仕事に対して
    その html を埋め込む
    watchlist button を埋め込む div が仕
    事ごとに用意されている

    View Slide

  63. 取得したデータ(json)に html が
    含まれているので?

    View Slide

  64. View Slide

  65. json に埋め込まれる html (※ 見やすさのために本来存在しない改行追加しています)

    View Slide

  66. View Slide

  67. json として html を受け取って、
    その html を dom にぶち込んでる

    View Slide

  68. 「気になる」ボタンが押された時はもちろん DOM の埋め込み直し

    View Slide

  69. JSON 色つけですらなく、
    DOM をそのまま埋め込み職人

    View Slide

  70. (余談)
    Q. watchlist の追加に失敗したら
    どうなるでしょう?

    View Slide

  71. A.
    Status Code: 200

    View Slide

  72. status コードは甘え。
    やる気があるなら payload の文字列で
    結果を判定しろ

    View Slide

  73. どうしようこれ

    View Slide

  74. そもそもどういう感じに
    なっていたら嬉しいか

    View Slide

  75. 期待する動作
    1. 画面初期化時は ajax でボタンの html(json) を取ってくるんじゃなくて、
    watchlist の状態だけもらっておいて Vue.js 側でボタンの出し分けをする
    2. 気になるボタンが押されたら、追加リクエストを送る
    3. 追加された watchlist の id をレスポンスで受け取り、取り消しボタンを表示する
    4. 取り消しボタンが押されたら、2で取得した id をつけて取り消しリクエストを送

    View Slide

  76. 課題は何か
    ● 取り消しリクエストには watchlist の id が必要
    ● 現状の watchlist 追加 API だと、レスポンス json の html の中に watchlist の id が埋まって
    いて取り出しにくい

    View Slide

  77. どうやって解決したか

    View Slide

  78. 現状の watchlist 追加 API のレスポンスに、
    追加された watchlist の id 加えてあげたら、
    影響少なそうだし実装の手間少ないし、
    やりたいこと実現できるし良いじゃん!!😈

    View Slide

  79. つまり
    レスポンスに新しく追加した watchlist_id を足して
    ● html
    ● message
    ● watchlist_id (NEW!)
    の 3 本立てで返してあげるようにする

    View Slide

  80. json に html が含まれている状態を
    放置することになるけどいいの...?

    View Slide

  81. View Slide

  82. という訳で
    ついでに成功したかど
    うかも返すことに

    View Slide

  83. めでたし!!!!

    View Slide

  84. まとめ

    View Slide

  85. 振り返り
    ● Vue3 + TypeScript は開発体験が良くて、書いていて楽しい
    ● レガシーフロントエンドの Vue.js への置き換えは、単純にはできなくて骨が折れる
    ● 削れる機能は削って、もっと楽したかった
    ● どうして...ってコードは、一周回って変な笑いが出る

    View Slide

  86. 大事なこと
    ● 目的を明確にして、やらないことを決める

    View Slide

  87. やめないこと

    View Slide

  88. Special Thanks
    ● OD さん
    ● yamanoku さん

    View Slide

  89. Thank you for listening !!

    View Slide