# 移行ビルド
# 概要
@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 (opens new window)、Quasar (opens new window)、ElementUI (opens new window)などのコンポーネントライブラリに依存している場合は、Vue 3 と互換性のあるバージョンを待つことをお勧めします。Internet Explorer 11 のサポート: Vue 3 は公式に IE11 サポートの計画を中止しました (opens new window)。まだ IE11 以下をサポートする必要がある場合は、Vue 2 のままにしておく必要があります。
サーバーサイドレンダリング: 移行ビルドは SSR にも使用できますが、カスタム SSR セットアップの移行はもっと複雑です。一般的な対処法は、
vue-server-renderer
を@vue/server-renderer
(opens new window)に置き換えることです。Vue 3 ではバンドルレンダラが提供されなくなったため、Vue 3 の SSR をVite (opens new window)で使用することが推奨されています。また、Nuxt.js (opens new window)を使用している場合は、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 に移行する手順を示しています。完全なコミットはこちら (opens new window)から確認できます。なお、実際に必要な手順はプロジェクトによって異なるため、これらの手順は厳密な指示ではなく一般的なガイダンスとして扱ってください。
# 準備
- まだ 非推奨の named/scoped スロット構文 (opens new window) を使用している場合は、まず最新の構文にアップデートしてください(構文は 2.6 ですでにサポートされています)。
# インストール
必要に応じてツールをアップグレードします。
- カスタム webpack セットアップを使用している場合:
vue-loader
を^16.0.0
にアップグレードします。 vue-cli
を使用している場合:vue upgrade
で最新の@vue/cli-service
にアップグレードします。- (代替手段) Vite (opens new window) + vite-plugin-vue2 (opens new window)に移行します。[コミット例 (opens new window)]
- カスタム webpack セットアップを使用している場合:
package.json
でvue
を 3.1 にアップデートし、同じバージョンの@vue/compat
をインストールます。またvue-template-compiler
(もしあれば) を@vue/compiler-sfc
に置き換えます。"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" }
1
2
3
4
5
6
7
8
9
10ビルド設定で、
vue
を@vue/compat
にエイリアスし、Vue のコンパイラオプションで compat モードを有効にします。設定のサンプル
vue-cli
// 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 } } } }) }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19Plain webpack
// webpack.config.js module.exports = { resolve: { alias: { vue: '@vue/compat' } }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { compatConfig: { MODE: 2 } } } } ] } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23Vite
// vite.config.js export default { resolve: { alias: { vue: '@vue/compat' } }, plugins: [ vue({ template: { compilerOptions: { compatConfig: { MODE: 2 } } } }) ] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19この時点で、あなたのアプリケーションは、いくつかのコンパイル時のエラーや警告に遭遇するかもしれません(例:フィルターの使用)。まずはそれらを修正してください。コンパイラの警告がすべて消えた場合は、コンパイラを Vue 3 モードに設定することもできます。
エラーを修正した後、前述の制限事項の対象になっていなければアプリを実行できるはずです。
コマンドラインとブラウザのコンソールの両方に、たくさんの警告が表示されると思います。ここでは一般的なヒントをご紹介します。
ブラウザのコンソールでは、特定の警告をフィルタリングすることができます。フィルタを使用して、一度に 1 つの項目を修正することに集中することをお勧めします。また、
-GLOBAL_MOUNT
のような否定のフィルタを使うこともできます。compat の設定で特定の非推奨事項を抑制することができます。
警告の中には、使用している依存関係(例:
vue-router
)が原因となっているものがあります。警告のコンポーネントトレースやスタックトレース(クリックで展開)から確認できます。まず、自分のソースコードに起因する警告の修正に集中してください。vue-router
を使用している場合は、vue-router
v4 にアップグレードするまで、<transition>
と<keep-alive>
は<router-view>
で動作しないことに注意してください。
<transition>
のクラス名 を更新します。これは、実行時の警告が出ない唯一の機能です。プロジェクト全体で.*-enter
と.*-leave
の CSS クラス名を検索することができます。新しいグローバルマウント APIを使用するようにアプリのエントリを更新します。
vuex-router
を v4 にアップグレード (opens new window)します。vuex-router-sync
も使用している場合は、ストアゲッターで置き換えることができます。アップグレード後、
<router-view>
で<transition>
や<keep-alive>
を使用するには、新しい scoped-slot ベースの構文 (opens new window) を使用する必要があります。個々の警告を取り除きます。一部の機能は、Vue 2 と Vue 3 の間で矛盾した動作をすることに注意してください。例えば、Render 関数 API や、関数型コンポーネントと非同期コンポーネントの変更などがあります。アプリケーションの他の部分に影響を与えずに Vue 3 の API に移行するには、
compatConfig
オプションを使用して、コンポーネントごとに Vue 3 の動作をオプトインすることができます。すべての警告が修正されたら、移行ビルドを削除して Vue 3 に正しく切り替えることができます。ただし、Vue 2 の動作に頼った依存関係が残っている場合は、切り替えできないことがあります。
# compat の設定
# グローバル設定
compat の機能は個別に無効にすることができます:
import { configureCompat } from 'vue'
// 特定の機能のために compat を無効にする
configureCompat({
FEATURE_ID_A: false,
FEATURE_ID_B: false
})
2
3
4
5
6
7
また、アプリケーション全体をデフォルトで Vue 3 の動作にして、特定の compat 機能だけを有効にすることもできます:
import { configureCompat } from 'vue'
// すべてを Vue 3 の動作にデフォルト化して、
// 特定の機能のみ compat を有効にする
configureCompat({
MODE: 3,
FEATURE_ID_A: true,
FEATURE_ID_B: true
})
2
3
4
5
6
7
8
9
# コンポーネントごとの設定
コンポーネントは compatConfig
オプションを使用することができます。このオプションには、グローバルの configureCompat
メソッドと同じオプションが指定できます:
export default {
compatConfig: {
MODE: 3, // このコンポーネントのみ Vue 3 の動作をオプトインする
FEATURE_ID_A: true // 機能をコンポーネントレベルで切り替えることも可能です
}
// ...
}
2
3
4
5
6
7
# コンパイラ固有の設定
COMPILER_
で始まる機能は、コンパイラ固有のものです。完全なビルド(ブラウザ内コンパイラ付き)を使用している場合は、実行時に設定することができます。しかし、ビルドセットアップを使用している場合は、代わりにビルド設定の compilerOptions
で設定する必要があります(上記の設定例を参照)。
# 機能リファレンス
# 互換性の種類
- ✔ 完全な互換性
- ◐ 注意点付きの部分的な互換性
- ⨂ 互換性なし(警告のみ)
- ⭘ compat のみ(警告なし)
# 互換性なし
前もって修正する必要がある、またはエラーになる可能性が高い
ID | 分類 | 説明 | ドキュメント |
---|---|---|---|
GLOBAL_MOUNT_CONTAINER | ⨂ | マウントされたアプリケーションは、マウント先の要素を置き換えません | link |
CONFIG_DEVTOOLS | ⨂ | production の devtools がビルド時のフラグになりました | link (opens new window) |
COMPILER_V_IF_V_FOR_PRECEDENCE | ⨂ | v-if と v-for が同じ要素で使われたときの優先順位が変更されました | link |
COMPILER_V_IF_SAME_KEY | ⨂ | v-if のブランチでは、同じキーを持つことができなくなりました | link |
COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENT | ⨂ | <template v-for> のキーは、<template> に置くことが必要になりました | link |
COMPILER_SFC_FUNCTIONAL | ⨂ | <template functional> は SFC でサポートされなくなりました | link |
# 注意点付きの部分的な互換性
ID | 分類 | 説明 | ドキュメント |
---|---|---|---|
CONFIG_IGNORED_ELEMENTS | ◐ | config.ignoredElements は config.compilerOptions.isCustomElement になりました(ブラウザコンパイラビルドでのみ)。ビルドセットアップを使用している場合は、isCustomElement をビルド設定で渡さなければなりません | link |
COMPILER_INLINE_TEMPLATE | ◐ | inline-template は削除されました(compat はブラウザのコンパイラビルドでのみサポートされます) | link |
PROPS_DEFAULT_THIS | ◐ | props のデフォルトファクトリは this にアクセスできなくなりました(compat モードに置いて this は実際のインスタンスではなく、props、$options および injections を公開しているだけになります) | link |
INSTANCE_DESTROY | ◐ | $destroy インスタンスメソッドは削除されました(compat モードでは、ルートインスタンスでのみサポートされています) | |
GLOBAL_PRIVATE_UTIL | ◐ | Vue.util はプライベートとなり、使用できなくなりました | |
CONFIG_PRODUCTION_TIP | ◐ | config.productionTip が不要になりました | link |
CONFIG_SILENT | ◐ | config.silent は削除されました |
# compat のみ(警告なし)
ID | 分類 | 説明 | ドキュメント |
---|---|---|---|
TRANSITION_CLASSES | ⭘ | トランジションの enter/leave クラスが変更されました | link |
# 完全な互換性
ID | 分類 | 説明 | ドキュメント |
---|---|---|---|
GLOBAL_MOUNT | ✔ | new Vue() -> createApp | link |
GLOBAL_EXTEND | ✔ | Vue.extend は削除されました(defineComponent またはextends オプションを使用してください) | link |
GLOBAL_PROTOTYPE | ✔ | Vue.prototype -> app.config.globalProperties | link |
GLOBAL_SET | ✔ | Vue.set は削除されました(不要になりました) | |
GLOBAL_DELETE | ✔ | Vue.delete は削除されました(不要になりました) | |
GLOBAL_OBSERVABLE | ✔ | Vue.observable は削除されました( reactive を使用してください) | link |
CONFIG_KEY_CODES | ✔ | config.keyCodes は削除されました | link |
CONFIG_WHITESPACE | ✔ | Vue 3 では、ホワイトスペースのデフォルトは "condense" になりました | |
INSTANCE_SET | ✔ | vm.$set は削除されました(不要になりました) | |
INSTANCE_DELETE | ✔ | vm.$delete は削除されました(不要になりました) | |
INSTANCE_EVENT_EMITTER | ✔ | vm.$on 、vm.$off 、vm.$once は削除されました | link |
INSTANCE_EVENT_HOOKS | ✔ | インスタンスが hook:x イベントを発行しなくなりました。 | link |
INSTANCE_CHILDREN | ✔ | vm.$children は削除されました | link |
INSTANCE_LISTENERS | ✔ | vm.$listeners は削除されました | link |
INSTANCE_SCOPED_SLOTS | ✔ | vm.$scopedSlots は削除されました。 vm.$slots は関数を公開するようになりました。 | link |
INSTANCE_ATTRS_CLASS_STYLE | ✔ | $attrs に class と style が追加されました | link |
OPTIONS_DATA_FN | ✔ | すべての場合において、data は関数であることが必要になりました | link |
OPTIONS_DATA_MERGE | ✔ | mixin や extension からの data が浅くマージされるようになりました | link |
OPTIONS_BEFORE_DESTROY | ✔ | beforeDestroy -> beforeUnmount | |
OPTIONS_DESTROYED | ✔ | destroyed -> unmounted | |
WATCH_ARRAY | ✔ | 配列の watch ではディープなものでない限り、 mutation を発行しなくなりました | link |
V_FOR_REF | ✔ | v-for の中の ref が refs の配列を登録しなくなりました | link |
V_ON_KEYCODE_MODIFIER | ✔ | v-on が keyCode 修飾子をサポートしなくなりました | link |
CUSTOM_DIR | ✔ | カスタムディレクティブのフック名が変更されました | link |
ATTR_FALSE_VALUE | ✔ | バインディングの値が真偽値の false の場合、属性を削除しないようになりました | link |
ATTR_ENUMERATED_COERSION | ✔ | 特殊なケースの列挙された属性は廃止されました | link |
TRANSITION_GROUP_ROOT | ✔ | <transition-group> は、デフォルトでルート要素をレンダリングしなくなりました | link |
COMPONENT_ASYNC | ✔ | 非同期コンポーネントの API が変更されました(defineAsyncComponent が必要になりました) | link |
COMPONENT_FUNCTIONAL | ✔ | 関数型コンポーネントの API が変更されました(プレーンな関数であることが必須になりました) | link |
COMPONENT_V_MODEL | ✔ | コンポーネントの v-model が再構築されました | link |
RENDER_FUNCTION | ✔ | Render 関数の API が変更されました | link |
FILTERS | ✔ | フィルタは削除されました(このオプションは、ランタイムのフィルタ API にのみ影響します) | link |
COMPILER_IS_ON_ELEMENT | ✔ | is の使用は <component> のみに制限されるようになりました | link |
COMPILER_V_BIND_SYNC | ✔ | v-bind.sync は v-model に置き換えられ、引数を持つようになりました | link |
COMPILER_V_BIND_PROP | ✔ | v-bind.prop 修飾子は削除されました | |
COMPILER_V_BIND_OBJECT_ORDER | ✔ | v-bind="object" は順番に注意が必要になりました | link |
COMPILER_V_ON_NATIVE | ✔ | v-on.native 修飾子は削除されました | link |
COMPILER_V_FOR_REF | ✔ | v-for 内の ref (コンパイラサポート) | |
COMPILER_NATIVE_TEMPLATE | ✔ | 特別なディレクティブを持たない <template> がネイティブな要素としてレンダリングされるようになりました | |
COMPILER_FILTERS | ✔ | フィルタ(コンパイラサポート) |
← はじめに v-forのref配列 →