MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

Vue 3 移行の技術 Tips

Vue 3 移行の技術 Tips

はじめに

半年前に弊社の画面プロジェクトの Vue 3 移行を担当した郭です。 本記事では、移行時に得た知見を整理し、実践的な技術 Tips を共有します。

全体的な移行アプローチ

試行錯誤の結果、公式の移行ガイドを活用するのが最もスムーズな方法でした。日本語版も提供されており、非常に参考になります。

また、Vue 3 への移行は単なるバージョンアップではなく、環境の整備やライブラリの更新、テストの強化を含む包括的な作業となりました。スムーズな移行を実現するため、以下のフローを採用しました。

  1. テスト環境の強化
  2. Node.js, Webpackのアップグレード
  3. node-sass -> sass 移行, vue-loader などライブラリのアップグレード
  4. @vue/compat を Vue2モードで導入
  5. VueRouter, Vuex, chart.js, vue-chart.js, vuejs-datepicker などライブラリのアップグレード
  6. @vue/compat をVue3モードに変更

このアプローチにより、大規模な変更を一括で行うのではなく、段階的に移行を進めることでリスクを最小限に抑え、スムーズな Vue 3 への移行を実現しました。

1. テスト環境の強化

Vue 3 への移行には多くのステップがあり、各段階で画面の挙動を確認することが重要です。しかし、すべてを目視でチェックするのは手間がかかる上に、チェック漏れが発生しやすいため、Playwright を用いた E2E テストの自動化を導入しました。

Playwright による UI テスト

テストでは、期待値の確認だけでなく、画面キャプチャを保存し、マスターブランチのキャプチャと比較することでレイアウトのズレも検出できるようにしました。

test('01_xxx作成_失敗', async ({}, testInfo) => {
  await page.getByRole('button', { name: 'xxx作成' }).click();
  await expect(page.getByText('yyy名')).toBeVisible();
  await page.getByText('yyy名').scrollIntoViewIfNeeded();
  await screenshotSave(page, testInfo);

  await page.getByRole('button', { name: '作成する' }).click();
  await expect(page.getByText('yyy名の入力は必須です。')).toBeVisible();
  await expect(page.getByText('xxxのいずれかが設定されている必要があります。')).toBeVisible();
  await screenshotSave(page, testInfo);
});

画像の差分比較には pixelmatch を使用しました。

差分があるピクセルが赤く表示されるため、視覚的に確認しやすいです。

  • 例(A)

  • 例(B)

  • AとBの差分

上記の例のように、ラベルの僅かなズレも検知してくれましたね。

CI/CD による開発サイクルの最適化

また、CI/CD によるテスト自動化を組み込み、開発サイクルを効率化しました。

  1. 実装の修正・ローカルテスト
  2. GitHub に PR を作成
  3. CI/CD でビルド・E2E テストを実行
  4. レビューとエビデンス確認
  5. PR をマージ

2. Node.js、Webpack のアップグレード

移行前の Node.js のバージョンは 10.15.0 でしたが、Vue 3 の必要環境として Node.js 18.3 以上 が推奨されています。そのため、まずは Node.js のバージョンを更新しました。

また、Vue 3 は Webpack 4 でも動作しますが、最新機能を活用するため Webpack 5 にアップグレードしました。

Node.js のバージョンアップ時の注意点

1. 依存ライブラリの互換性チェック

  • Node.js のバージョンを上げると、一部の古いライブラリが非互換になる可能性があります。
  • nvm を使用して、一時的に古いバージョンに戻せる環境を整えておくと安全です。

2. node_modules の再インストール

  • rm -rf node_modules package-lock.json を実行し、npm install することで、不整合を防ぎます。

3. npm のバージョン調整

  • Node.js を更新すると、npm のバージョンも変更されるため、npm -v で確認し、必要に応じて npm install -g npm で更新します。

4. ビルドツールの更新

  • Webpack や Babel などのビルドツールが古いとエラーが発生することがあるため、適宜アップデートが必要です。

3. Sass の移行

node-sass は非推奨となっており、公式推奨の sass (Dart Sass) へ移行しました。

Sass への移行時の注意点

1. @import の非推奨化

  • @import は非推奨となり、@use への移行が必要です。
  • これに伴い、変数や mixin のスコープ管理が変わるため、調整が必要です。

2. ネストの挙動の変更

  • Dart Sass では CSS の標準仕様により厳密なネストルールが適用されます。
  • & の使い方、一部変更される可能性があるため、スタイルの適用範囲を確認します。

3. ビルド時間の変化

  • Dart Sass は JavaScript で動作するため、環境によってはビルド時間が増加することがあります。

4. @vue/compat を Vue 2 モードで導入

Vue 3 に移行する際、まずは @vue/compat を Vue 2 モードで導入し、徐々に Vue 3 へ移行する方法を採用しました。

  • vue.config.js@vue/compat を有効化し、Vue 2 の記述で動作させました。

  • Vue.use の削除や $listeners の扱いの変更を事前に対応することで、後の Vue 3 への完全移行をスムーズにしました。

  • Vue 3 では vue-template-compiler が 非推奨 となり、代わりに @vue/compiler-sfc を使用する必要があります。 vue-loader のバージョンアップと同時に適用することで、エラーを最小限に抑えられました。

5-1. chart.js/vue-chartjs のバージョンアップ

Vue 3 では vue-chartjs も大きく変更されており、以下のバージョンに更新しました。

-    "chart.js": "^2.7.2",
+    "chart.js": "^4.4.4",
-    "vue-chartjs": "^3.5.0",
+    "vue-chartjs": "^5.3.1",

バージョン移行ガイド

移行時の注意点

1. API の変更

  • options の構造が変更され、responsivemaintainAspectRatio の扱いが異なります。

2. デフォルト設定の変更

  • 一部のデフォルト値が変更されたため、明示的な設定が必要になります。

3. 型定義の強化

  • TypeScript を使用している場合、型エラーが発生する可能性があるため、適切な修正が必要です。

また、カスタムコンポーネントの移行が課題でしたが、リアルタイムで試せるツール(CodeSandbox など)を活用することでスムーズに対応できました。

5-2. vuejs-datepicker から vue3-datepicker への移行

Vue 3 に対応した日付ピッカーをいくつか比較した結果、vue3-datepicker を採用しました。

いくつかの候補を比較した結果、機能が充実しており、既存のコードの改修量が最も少なかったため、vue3-datepicker を採用しました。

6. @vue/compat を Vue 3 モードに変更

最終的に @vue/compat を Vue 3 モードに変更し、完全に Vue 3 へ移行しました。

変更時の注意点

1. 互換モードで動いていたコードの再確認

  • @vue/compat を Vue 3 モードにしますと、一部の Vue 2 の構文が完全に無効になります。
  • Vue.use() で登録していたプラグインが正しく動作するか、依存ライブラリが Vue 3 対応済みか確認しました。

2. v-model の変更

  • v-modelpropevent の仕様が Vue 3 では変わるため、カスタムコンポーネントでの v-model の使い方を修正しました。

3. globalProperties の適用

Vue.prototype に追加していたグローバル変数は app.config.globalProperties に書き換えました。

まとめ

Vue 3 への移行には、単にコードを修正するだけでなく、テスト環境の整備ライブラリの更新も不可欠でした。特に E2E テストの自動化により、移行作業の負担を軽減できた点は大きなメリットでした。

今後、Vue 3 の Composition API への完全移行や、Pinia の活用など、さらなる最適化を検討していきたいです。