Slide 1

Slide 1 text

Viteに移行した話とVue-demiで Vue2と3両対応のコンポーネント を作った話 株式会社フォーエス 吉川 真司

Slide 2

Slide 2 text

自己紹介  株式会社フォーエスで、社内の実験的な技術開拓を行うエンジニアをしていま す。  以前は、LAMP環境のサーバー構築やメンテ、PHPなど主にバックエンドをメ インにやっていましたが、現職では上記以外にもJavaもやったりしています。  今後のキャリアプランとしてUXを極めたいと考えており、その上でLaravelを 通じて知ったのがVueです。

Slide 3

Slide 3 text

Vue CLIが重い!  以前WikiシステムでjQueryの代わりに部分的に使っていたVueが思いの外早 かったので、FEで完結するシングルページアプリケーションを作ってみようと 考え、試しにゲーム用の地図サイトをVue2とVueCLIを使って作っていました。  しばらく、VueCLIでプロダクトを開発していたが、だんだん処理が重くなり 開発サーバーが起動するまで1分半かかるようになってきました。  また、Node 17になってからOpenSSL周りの仕様が変わり、そもそもVueCLI のミドルウェアであるWebpackが動作しなくなりました。  そんな中Viteというのが話題になっており、完全に見切り発進の状態で移行す ることにしました。

Slide 4

Slide 4 text

Viteへの移行  そこで、 ViteをVue2で動くよう改造(当時はvite-plugin-vue2を使っていまし た)し、 最小限構成で動かすvite-vue2-starterというプロジェクトを作りまし た。これは、今まで使用していた環境(eslint設定など)を移植したものです。 https://github.com/logue/vite-vue2-ts-starter  このような、最小限構成のテンプレートプロジェクトを作ることにより、最新 への追従コストを下げることに成功しました。  また、当初は開発言語を JavaScript から TypeScript に移行していた時期で、 開発例として多かった vue-property-decorator と vue-class-components を用 いて作成していました。

Slide 5

Slide 5 text

Composition APIへの移行  早くなったのは良かったのですが、その直後デフォルトでインストールされる Vueが3になったことで、早々に困ったことになりました。  UIフレームワークにVuetifyとBootstrapVueを採用していましたが、Vuetifyはα 版、BootstrapVueは開発計画どころか、Bootstrap5にも対応していない状態で あり、Vue3に移行するのは時期尚早であるというのと、Vue3からは今までの書 き方が使えずComposition APIになるということでそれまで作っていたvue- property-decoratorが実質使えなくなる(可能性が高い)ということでした。  そこで出した結論は、当面Vue2を使いつつもComposition APIに移行し、各種UI フレームワークが対応次第Vue3に移行するということでした。  また、同時期に発見したVue demiでVue2/Vue3両対応のプログラムが書けると いうことと、そのライブラリがComposition API前提だったというのも後押しし ました。

Slide 6

Slide 6 text

Vue-demiで作るvue-codemirror6コン ポーネント  自分は昔から、編集フォームにも適応できる便利なシンタックスハイライター でとして CodeMirror 好んで使っており、Vueに移行した後もvue-codemirrorを 使っていました。  以下のようにシンタックスハイライトができて、かつ編集可能なのが特徴です。  未完ながら、昔PukiWIki文法用のCodeMirror用のプラグインを作ったりしてい ました。

Slide 7

Slide 7 text

Vue-demiで作るvue-codemirror6コン ポーネント  しかし、vue-codemirrorは当時長らくメンテされておらず、最新の CodeMirror6 に対応していませんでした。  当時作っていたVueプロダクトで、直接APIを叩く形でCodeMirror6を使ってお り、自力でラッパーを作っていたのでこれを外部化しようとしていたところ Vue-demiという便利なライブラリがあることに気づきました。  Vue-demiは、Vue2とVue3両対応のライブラリをビルドするためのラッパーラ イブラリです。  初期バージョンはVue2向けにpropertey-decoratorで作っていましたが、vue- demiに対応させるためプロダクト側のComposition API化と並行して作業を行 いました。  以降、これ以外のコンポーネントでもComposition API化と疎結合化をすすめ、 コンポーネントの開発はVue3で行い、それをVueDemiでVue2に移植するという 方針で行っています。

Slide 8

Slide 8 text

Markdownエディタの例 今回のvie-codemirror6で作ったリアルタイムMarkdownエディタです。v-modelで動くようにしてあり、左のエディタで Markdownを編集するとリアルタイムで右ペインのMarkdown-wasmによるプレビューが反映されます。

Slide 9

Slide 9 text

Vue-demiでハマったところ  Vue-demiでVue2用のコードとVue3用のコードを共通化するところまではでき ましたが、いざビルドしてみるとVue2環境でビルドしたものとVue3環境でビル ドしたもので互換性のないコードになってしまう問題が発生しました。  原因を探るとVueのh関数の差を吸収するコードが無いことが原因でした。  そこで、vue-demiのisuue( https://github.com/vueuse/vue- demi/issues/65)に上がっていたh-demi.tsをカスタマイズしたものを使うこと で解決しました。

Slide 10

Slide 10 text

困った事  この記事を執筆した当時、UIフレームワークのVuetifyがVue3に対応していない ことも有りViteでスターターテンプレートを作ってメンテナンスしていました が、vue-tsc側でvue2で許容されている書き方でNGとされる部分が増えてきた ため、そろそろ限界が来ています。(例:v-checkboxのv-modelとvalueを併用 するパターン)

Slide 11

Slide 11 text

所感  CompositionAPIへの移行はコツを掴んでしまえばあっという間に終わりました。  今年の2月から3ヶ月かけてすべてのプロダクトの移行が完了しました。  試しにVue3で動かしてみましたが、UIライブラリ(Vuetify3 v3beta)の実装状況に 起因するエラー以外はすんなり動きそうでした。  ただ、説明サイトを見るだけだとやっぱりメリットを見出すのは難しいです。実際 手を動かして作業することで気がつくことが多いです。  少なくとも2013年頃から自分は、言語を問わずコード整形ツールを活用する習慣が あり、Vueを触った当初からeslintやprettierの設定をキツ目にしていました。  また、たまたま自動インストールされたsonarlintがvueのtypescriptにも作用したた めトラブルが少なかったというのも考えられます。(それでも、v-modelに.sync修 飾子がついている前提で使用するライブラリがあって悩んだことがありますが)

Slide 12

Slide 12 text

作ったミドルウェアの紹介  vite-vue2-starter Viteでvue2を使うための最小限のライブラリを集めたスターターテンプレート  vite-vue2-vuetify-ts-starter 上記のテンプレートにVuetifyを追加したもの  @logue/vue2-helpers Vue2でVue-routerやVuexなどをVue3風のComposition APIで書くためのラッ パーライブラリ。これのフォーク版を作り、VuetifyとVue3のteleportに対応さ せた。  vue-inertia-composable Laravel9用Laravel BreezeをVue2でも使えるようにするためのミドルウェア。