Skip to content

移行ビルド

概要

@vue/compat(別名「移行ビルド」)は、設定可能な Vue 2 互換の動作を提供する、Vue 3 のビルドです。

移行ビルドはデフォルトで Vue 2 モードで動作します。ほとんどの公開 API はいくつかの例外を除いて、Vue 2 とまったく同じように動作します。Vue 3 で変更または非推奨となった機能を使用すると、実行時警告が表示されます。機能の互換性はコンポーネント単位で有効化/無効化できます。

想定しているユースケース

  • Vue 2 アプリケーションを Vue 3 にアップグレードする(制限あり)
  • Vue 3 に対応するためのライブラリーの移行
  • Vue 3 をまだ試していない経験豊富な Vue 2 開発者にとって、Vue 3 の代わりに移行ビルドを使用することで、バージョン間の違いを学ぶことができます。

既知の制限

移行ビルドは Vue 2 の動作をできるだけ模倣するよう努力していますが、いくつかの制限があるため、アプリをアップグレードの対象にできない場合があります:

  • Vue 2 の内部 API やドキュメントにはない動作に依存する依存関係。最も一般的なケースは、VNodes のプライベートプロパティの使用です。あなたのプロジェクトが Vuetify, Quasar, ElementUI のようなコンポーネントライブラリーに依存している場合、それらの Vue 3 互換バージョンを待つのが最善です。

  • Internet Explorer 11 対応: Vue 3 は IE11 対応の計画を正式に取りやめました。まだ IE11 以下のサポートが必要な場合は、Vue 2 のままにしておく必要があります。

  • サーバーサイドレンダリング: 移行ビルドは SSR にも使えますが、カスタム SSR セットアップの移行はもっと複雑です。vue-server-renderer@vue/server-renderer に置き換えるのが一般的です。Vue 3 ではバンドルレンダラーが提供されなくなったので、Vue 3 の SSR を Vite で使用することが推奨されています。Nuxt.js を使用している場合は、Nuxt 3 を待つ方がよいでしょう。

期待されること

移行ビルドは、公開されている Vue 2 の API と動作のみをカバーすることを目的としていることにご注意ください。ドキュメントにはない動作に依存していることにより移行ビルドでアプリケーションが実行できない場合、その特定のケースに対応するために移行ビルドを調整することはまずありません。代わりに、問題のある動作への依存を取り除くためのリファクタリングを検討してください。

注意: アプリケーションが大規模で複雑な場合、移行ビルドを使用しても移行は困難である可能性が高いです。もしあなたのアプリが残念ながらアップグレードに適さない場合、Composition API と他のいくつかの Vue 3 機能を 2.7 リリースでバックポートする予定であることに注意してください(2021 年第 3 四半期後半に予定)。

移行ビルドでアプリを動作させる場合でも、移行が完了する前にプロダクション環境へ出荷できます。パフォーマンスやサイズのオーバーヘッドが若干発生しますが、プロダクション環境の UX に顕著な影響を与えることはないでしょう。Vue 2 の動作に依存する依存関係があってアップグレードや置き換えができない場合は、そのようにする必要があるかもしれません。

移行用ビルドは 3.1 から提供され、3.2 のリリースラインと同時に公開され続けます。将来のマイナーバージョン(2021 年末以降)で移行用ビルドの公開を終了する予定ですので、それまでに標準ビルドへの移行を目指す必要があります。

アップグレードのワークフロー

以下のワークフローでは、実際の Vue 2 アプリ(Vue HackerNews 2.0)を Vue 3 に移行するステップを説明します。完全なコミットは、こちらで見ることができます。あなたのプロジェクトに必要な実際の手順は異なる可能性があり、これらの手順は厳密な指示ではなく、一般的なガイダンスとして扱われるべきであることに注意してください。

準備

インストール

  1. 該当する場合はツールをアップグレードします。

    • カスタム webpack セットアップを使用している場合: vue-loader^16.0.0 にアップグレードしてください。
    • vue-cli を使用している場合: vue upgrade を使って、最新の @vue/cli-service にアップグレードしてください
    • (代替)Vite + vite-plugin-vue2 に移行する。[コミットの例]
  2. package.jsonvue を 3.1 に更新し、同じバージョンの @vue/compat をインストールし、もし vue-template-compiler が存在すれば @vue/compiler-sfc で置き換えます:

    diff
    "dependencies": {
    -  "vue": "^2.6.12",
    +  "vue": "^3.1.0",
    +  "@vue/compat": "^3.1.0"
       ...
    },
    "devDependencies": {
    -  "vue-template-compiler": "^2.6.12"
    +  "@vue/compiler-sfc": "^3.1.0"
    }
    

    コミットの例

  3. ビルド設定で vue@vue/compat にエイリアスし、Vue コンパイラーオプションで互換モードを有効にします。

    設定の例

    vue-cli
    js
    // vue.config.js
    module.exports = {
      chainWebpack: (config) => {
        config.resolve.alias.set('vue', '@vue/compat')
    
        config.module
          .rule('vue')
          .use('vue-loader')
          .tap((options) => {
            return {
              ...options,
              compilerOptions: {
                compatConfig: {
                  MODE: 2
                }
              }
            }
          })
      }
    }
    
    Plain webpack
    js
    // webpack.config.js
    module.exports = {
      resolve: {
        alias: {
          vue: '@vue/compat'
        }
      },
      module: {
        rules: [
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                compatConfig: {
                  MODE: 2
                }
              }
            }
          }
        ]
      }
    }
    
    Vite
    js
    // vite.config.js
    export default {
      resolve: {
        alias: {
          vue: '@vue/compat'
        }
      },
      plugins: [
        vue({
          template: {
            compilerOptions: {
              compatConfig: {
                MODE: 2
              }
            }
          }
        })
      ]
    }
    
  4. TypeScript を使用している場合は、以下のように *.d.ts ファイルを追加して、(Vue 3 では存在しなくなった)デフォルトエクスポートを公開するよう vue の型付けを変更する必要があります:

    ts
    declare module 'vue' {
      import { CompatVue } from '@vue/runtime-dom'
      const Vue: CompatVue
      export default Vue
      export * from '@vue/runtime-dom'
      const { configureCompat } = Vue
      export { configureCompat }
    }
    
  5. この時点で、アプリケーションはいくつかのコンパイル時のエラーや警告(例: フィルタの使用)に遭遇するかもしれません。まずそれらを修正します。すべてのコンパイラーの警告が消えたら、コンパイラーを Vue 3 モードに設定することもできます。

    コミットの例

  6. エラーの修正後、上記の制限に該当しなければ、アプリは実行できるはずです。

    コマンドラインとブラウザのコンソールの両方から、多くの警告が表示されるでしょう。ここでは、一般的なヒントをいくつか紹介します:

    • ブラウザコンソールで特定の警告をフィルタリングできます。フィルターを使い、一度に 1 つの項目を修正するのがよいでしょう。また、-GLOBAL_MOUNT のような否定的なフィルターも使用できます。

    • 互換性の設定を使って、特定の非推奨を抑制できます。

    • 一部の警告は、使用している依存関係(例: vue-router)が原因となっている場合があります。これは、警告のコンポーネントトレースやスタックトレース(クリックすると展開されます)から確認できます。まずは自分のソースコードに起因する警告を修正することに専念してください。

    • vue-router を使用している場合、<transition><keep-alive>vue-router v4 にアップグレードするまで <router-view> で動作しないので注意してください。

  7. <transition> のクラス名を更新します。これは実行時の警告がない唯一の機能です。.*-enter.*-leave の CSS クラス名をプロジェクト全体で検索できます。

    コミットの例

  8. 新しいグローバルマウント API を使用するようにアプリのエントリーを更新します。

    コミットの例

  9. vuex を v4 にアップグレードします。

    コミットの例

  10. vue-router を v4 にアップグレードします。vuex-router-sync も使っている場合は、ストアゲッターに置き換えることができます。

    アップグレード後、<transition><keep-alive><router-view> で使用するには、新しいスコープ付きスロットベースの構文を使用する必要があります。

    コミットの例

  11. 個々の警告を取り除きます。一部の機能では、Vue 2 と Vue 3 との間で矛盾する動作があることに注意してください - 例えば、レンダー関数 API または関数型コンポーネントと非同期コンポーネントの変更などです。アプリケーションの残りの部分に影響を与えずに Vue 3 の API へ移行するには、compatConfig オプションを使用してコンポーネントごとに Vue 3 の動作にオプトインできます。

    コミットの例

  12. すべての警告が修正されたら、移行ビルドを削除して Vue 3 に正しく切り替えることができます。ただし、Vue 2 の動作に依存する依存関係が残っている場合は、切り替えができない可能性があることに注意してください。

    コミットの例

互換性の設定

グローバル設定

互換機能は個別に無効化できます:

js
import { configureCompat } from 'vue'

// 特定の機能の互換性を無効化
configureCompat({
  FEATURE_ID_A: false,
  FEATURE_ID_B: false
})

または、特定の互換機能のみを有効化し、アプリケーション全体はデフォルトで Vue 3 の動作にできます:

js
import { configureCompat } from 'vue'

// デフォルトですべてを Vue 3 の動作にして、特定の機能の
// 互換性のみを有効化
configureCompat({
  MODE: 3,
  FEATURE_ID_A: true,
  FEATURE_ID_B: true
})

コンポーネントごとの設定

コンポーネントで compatConfig オプションを使用できます。このオプションはグローバルの configureCompat メソッドと同じオプションを受け付けます:

js
export default {
  compatConfig: {
    MODE: 3, // このコンポーネントのみ Vue 3 の動作にオプトイン
    FEATURE_ID_A: true // 機能はコンポーネントレベルでも切り替え可能
  }
  // ...
}

コンパイラー固有の設定

COMPILER_ で始まる機能は、コンパイラー固有のものです。フルビルド(ブラウザ内コンパイラーつき)を使用している場合、実行時に設定できます。ただしビルドセットアップを使用している場合は、代わりにビルド設定の compilerOptions を使用して設定する必要があります(上記の設定例を参照)。

機能リファレンス

互換性の種類

  • ✔ 完全に互換
  • ◐ 部分的な互換性(注意事項あり)
  • ⨂ 互換性なし(警告のみ)
  • ⭘ 互換性のみ(警告なし)

互換性なし

事前に修正すべきで、そうしないとエラーが発生する可能性が高いです

IDTypeDescriptionDocs
GLOBAL_MOUNT_CONTAINERマウントされたアプリケーションは、そこにマウントされている要素を置き換えませんlink
CONFIG_DEVTOOLSproduction devtools はビルド時のフラグになりましたlink
COMPILER_V_IF_V_FOR_PRECEDENCE同じ要素で使用した場合の v-ifv-for の優先順位は変更されましたlink
COMPILER_V_IF_SAME_KEYv-if のブランチは同じキーを持つことができなくなりましたlink
COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENT<template v-for> のキーは <template> に配置するようになりましたlink
COMPILER_SFC_FUNCTIONAL<template functional> は SFC でサポートされなくなりましたlink

部分的な互換性(注意事項あり)

IDTypeDescriptionDocs
CONFIG_IGNORED_ELEMENTSconfig.ignoredElementsconfig.compilerOptions.isCustomElement になりました(ブラウザコンパイラビルドのみ)。ビルドセットアップを使用している場合、isCustomElement はビルド設定で渡す必要があります。link
COMPILER_INLINE_TEMPLATEinline-template は削除されました(ブラウザコンパイラビルドでのみ互換性がサポートされます)link
PROPS_DEFAULT_THISprops の default ファクトリーは this にアクセスできなくなりました(互換モードでは、this は実際のインスタンスではありません - props, $options とインジェクションだけを公開します)link
INSTANCE_DESTROYインスタンスメソッド $destroy は削除されました(互換モードではルートインスタンスでのみサポート)
GLOBAL_PRIVATE_UTILVue.util は非公開になり利用できなくなりました
CONFIG_PRODUCTION_TIPconfig.productionTip は不要になりましたlink
CONFIG_SILENTconfig.silent は削除されました

互換性のみ(警告なし)

IDTypeDescriptionDocs
TRANSITION_CLASSESトランジションの enter/leave クラスの変更link

完全に互換

IDTypeDescriptionDocs
GLOBAL_MOUNTnew Vue() -> createApplink
GLOBAL_EXTENDVue.extend は削除されました(defineComponentextends オプションを使用してください)link
GLOBAL_PROTOTYPEVue.prototype -> app.config.globalPropertieslink
GLOBAL_SETVue.set は削除されました(不要になりました)
GLOBAL_DELETEVue.delete は削除されました(不要になりました)
GLOBAL_OBSERVABLEVue.observable は削除されました(reactive を使用してください)link
CONFIG_KEY_CODESconfig.keyCodes は削除されましたlink
CONFIG_WHITESPACEVue 3 では空白のデフォルトは "condense" です
INSTANCE_SETvm.$set は削除されました(不要になりました)
INSTANCE_DELETEvm.$delete は削除されました(不要になりました)
INSTANCE_EVENT_EMITTERvm.$on, vm.$off, vm.$once は削除されましたlink
INSTANCE_EVENT_HOOKSインスタンスは hook:x イベントを発行しなくなりましたlink
INSTANCE_CHILDRENvm.$children は削除されましたlink
INSTANCE_LISTENERSvm.$listeners は削除されましたlink
INSTANCE_SCOPED_SLOTSvm.$scopedSlots は削除されました。vm.$slots は関数を公開するようになりましたlink
INSTANCE_ATTRS_CLASS_STYLE$attrsclassstyle が含まれるようになりましたlink
OPTIONS_DATA_FNdata はどんな場合でも関数にする必要がありますlink
OPTIONS_DATA_MERGEmixins や extends からの data は浅いマージになりましたlink
OPTIONS_BEFORE_DESTROYbeforeDestroy -> beforeUnmount
OPTIONS_DESTROYEDdestroyed -> unmounted
WATCH_ARRAY配列の監視をする際、deep でなければ配列の変更でトリガーされなくなりましたlink
V_ON_KEYCODE_MODIFIERv-on は keyCode 修飾子をサポートしなくなりましたlink
CUSTOM_DIRカスタムディレクティブのフック名が変更されましたlink
ATTR_FALSE_VALUEバインドしている値が false でも、属性は削除されなくなりましたlink
ATTR_ENUMERATED_COERCION列挙型属性の特殊ケースは廃止link
TRANSITION_GROUP_ROOT<transition-group> はデフォルトではルート要素をレンダリングしなくなりましたlink
COMPONENT_ASYNC非同期コンポーネントの API 変更(defineAsyncComponent が必要になりました)link
COMPONENT_FUNCTIONAL関数型コンポーネントの API 変更(普通の関数にする必要があります)link
COMPONENT_V_MODELコンポーネントの v-model 改訂link
RENDER_FUNCTIONレンダー関数の API 変更link
FILTERSフィルターは削除されました(このオプションは実行時のフィルター API のみに影響)link
COMPILER_IS_ON_ELEMENTis の使用は <component> のみに制限されましたlink
COMPILER_V_BIND_SYNCv-bind.sync は引数つきの v-model に置き換わりましたlink
COMPILER_V_BIND_PROPv-bind.prop 修飾子は削除されました
COMPILER_V_BIND_OBJECT_ORDERv-bind="object" は順序に依存するようになりましたlink
COMPILER_V_ON_NATIVEv-on.native 修飾子は削除されましたlink
COMPILER_V_FOR_REFv-for 内の ref(コンパイラーサポート)
COMPILER_NATIVE_TEMPLATE特別なディレクティブなしの <template> は、ネイティブ要素としてレンダリングされるようになりました
COMPILER_FILTERSフィルター(コンパイラーサポート)