Vue v1.x から v2.x へアップデートした
Vue v1.0.15 から最新の v2.2.4 へアップデートしたのでメモ。かかった時間は2日程度だった(ついでにやった Browserify から Webpack への移行も含む)。
全体を通して、内部実装は大きく変わったが API 自体は v1 とある程度互換性があるので、vue-migration-helper の指示通りに変更して、テンプレートのエラー(正確にはコンパイル後の render 関数のエラー)を直せば、後はそのまま動くという印象。
手順
- https://github.com/vuejs/vue-migration-helper の警告メッセージに対応する。
- エラーをひたすら直す。
vue-migration-helper の警告メッセージに対応する
自分が対応した警告メッセージは以下のもの。大体は、エディタの置換機能で対応することができた。
- https://jp.vuejs.org/v2/guide/migration.html#ready-置き換え
- ready → mounted。フックで DOM 要素を参照していた場合は、nextTick でラップする
- https://jp.vuejs.org/v2/guide/migration.html#フィルタ引数の構文-変更
- https://jp.vuejs.org/v2/guide/migration.html#v-bind-への-once-と-sync-修飾子-削除
- パフォーマンス最適化のために once 修飾子をあちこちで使っていた
- https://jp.vuejs.org/v2/guide/migration.html#オブジェクトにおいての-v-for-の引数の順序-変更
- https://jp.vuejs.org/v2/guide/migration.html#v-el-と-v-ref-置き換え
- https://jp.vuejs.org/v2/guide/migration.html#literal-ディレクティブの修飾子-削除
- https://jp.vuejs.org/v2/guide/migration.html#HTML-の展開-削除
- https://jp.vuejs.org/v2/guide/migration.html#vm-set-変更
- set の際に ‘a.b’ のような子孫を対象にする key の指定が不可能になった
- https://jp.vuejs.org/v2/guide/migration.html#フィルタ外でのテキスト展開-削除
- ディレクティブの値としてフィルタが使用できなくなった。代わりにメソッドや算出プロパティを定義する必要があって、この中で一番面倒だった
- https://jp.vuejs.org/v2/guide/migration.html#dispatch-および-broadcast-置き換え
- https://jp.vuejs.org/v2/guide/migration.html#カスタムディレクティブ-単純化
- https://jp.vuejs.org/v2/guide/migration.html#transition-属性-置き換え
transition コンポーネントをラップするコンポーネント
コンポーネントオプション
export default { name: 'foo-transition', props: [], methods: { enter(el, done) { // ... }, enterCancelled(el) { // ... }, leave(el, done) { // ... }, leaveCancelled(el) { // ... } } };
テンプレート
<transition v-on:enter="enter" v-on:enter-cancelled="enterCancelled" v-on:leave="leave" v-on:leave-cancelled="leaveCancelled" v-bind:css="false" > <slot></slot> </transition>
使うときは以下のように。
<foo-transition> <p v-if="bar">Hi!</p> </foo-transition>
エラーをひたすら直す
一通りページを見て、発生しているエラーを片っ端から直した。
内部実装が大きく変わったので、以前はエラーにならなかった未定義のプロパティ・メソッドへの参照がエラーになった。
null チェックも厳しく行う必要があった。以前は以下のテンプレートで問題なかったが、
<div v-if="foo"> <p v-if="foo.bar"></p> </div>
このように書き直す必要があった。
<div v-if="foo"> <p v-if="foo && foo.bar"></p> </div>
v-if や v-show でロジックがテンプレートに漏れがちなので、メソッドや算出プロパティに置き換える良い機会なのかもしれない。
その他、あらかたエラーを直した後に Integration 環境に deploy して、社内の JavaScript のエラー集約の仕組み(Bugsnag や Newrelic にもあるやつ)でエラーが起きていないか確認した。
また、QA/テストエンジニアの人にリグレッションテストを依頼して、一通り問題がないか確認してもらった。
Vue(ライブラリ)のバージョンアップのために普段気をつけていること・思っていること
普段、なにとなく意識していることを言語化しておきます。
- (当たり前な気がするが)ガイドや API ドキュメントをよく読んで、その API が提供されている理由を理解した上で使う。
- たまたま動くからといって、意図されていない形では使わない。真っ先に壊れる
- Vue.nextTick や setTimeout(fn, 0) で実行を遅らせて動いているコードも壊れやすい
- 内部実装に近いフック・フラグ・API の使用をできるだけ避ける
- ちょっとした便利なオプション・エッジケースで必要になるオプションも避ける
- メジャーバージョンアップに伴う整理で廃止される可能性が高い
- 公式ではない Vue に依存した UI コンポーネントライブラリもなるだけ避ける
- よほど広く使われているものでなければ、メンテナンスされない可能性が高い(GitHub の Star の数や Contributers の数で判断)
- コードを読んで、4, 500 行以下であれば、実装を参考にさせてもらい自分で書く
- 開発スケジュールとの兼ね合いで使う場合は、最終的に自分で引き受けるぐらいの気持ちで使う
- ビルドツール・モジュールバンドラ等と強く依存する機能の使用には慎重になる
- v2 だと Webpack と連携する機能が次々と追加されていて、使うメリットもあるが、Webpack に依存する分、Webpack が捨てづらくなるデメリットもあることを理解する
- 悩んだら「置換や書き捨てのスクリプトでなんとかできるか」で思考実験する
- 悩んだら「他のツール・ライブラリで置き換えることができるか」で思考実験する
こんなところです。