Share
Embed
サービス開発におけるVue3とTypeScriptの親和性について
2024年5月11日(土)に開催された TSKaigi 2024 のセッションで発表したスライドになります。
Vue3がリリースされ、早くも4年弱経とうとしています、Vue2のLTSも2023年末に終了し、新規開発ではVue3を利用することが主流となってきました。
Vueと並ぶフレームワークとしてReactがありますが、未だにReactと比較される際、TypeScript対応が…という噂がたまに聞こえてきます。しかして、Vue3とTypeScriptの親和性は実際のところどうなのでしょうか。Piniaやその他ツールチェイン側などと共にVue3の機能や実際の実装例とともにVue3とTypeScriptの親和性の疑問を解消できるような発表にできればと思っています。
https://tskaigi.org/talks/karan_corons
karacoro / からころ
May 11, 2024
Transcript
65 slides
-
Copyright © LIXIL Corporation. All rights reserved. サービス開発における Vue3とTypeScriptの親和性について からころ(@karan_corons)
/ Tsukuha Kawakami TSKaigi 2024 株式会社LIXIL Marketing Dev Ops. System Dev. & Ope. Digital E-Application Exp -
2 自己紹介 - HN / Name - からころ(@karan_corons)/ Tsukuha Kawakami
- 所属 - 株式会社LIXIL - やっていること - MyLIXILという共通認証基盤の開発・運用 .etc - フロントエンドを基軸にバックエンドからクラウド, CI/CDまで - Zennでの技術記事の執筆など - よく使う技術 - TypeScript, JavaScript, Node.js, Vue.js .etc -
3 アジェンダ 1. はじめに 2. Vue.jsの概要 3. Vue.jsコミュニティ発のツールチェインについて 4. Vue.jsのTypeScript対応の経緯について
5. 状態管理と型 6. 型を利用してデータフローを可視化しよう 7. おわりに -
4 聞いてほしい方・話さないこと 聞いてほしい方 - Vue2からVue3への移行で悩んだことのある方 - Vue2の経験はあるけど、Vue3はあまり触っていない方 - その他、フロントエンドTypeScriptに興味がある方 .etc
話さないこと - Vueやその他ツールチェインの環境構築について - モダンフロントエンドフレームワークの基礎的内容 - Vue.jsの細かい仕様やTypeScriptに関係しないこと -
6 はじめに 話したいこと - Vue2も昨年末でEOLを迎えましたが、Vue2からVue3にかけて TypeScript対応はどういう経緯を辿ったか - Vue3が正式リリースされてすでに4年弱経っている現在 Vue3とTypeScriptの親和性は具体的にどうなっているか 今日持ち帰って欲しいこと
- Vue3とTypeScriptの親和性への理解 - 実際に用意しているテストリポジトリで実感 -
9 Vue.jsの概要 1 Web ユーザーインタフェース 構築のための、親しみやすく、 パフォーマンスと汎用性の高い フレームワークです。 pages/index.vue Child1.vue
index.vue 右図のようにVue SFCを作成 できます。 -
13 Vue.jsの概要 4 逆に子コンポーネントから、 親コンポーネントへのデータ の受け渡しは、 Event Emitting を利用し、 このように書けます。
components/Child.vue -
14 Vue.jsの概要 4 逆に子コンポーネントから、 親コンポーネントへのデータ の受け渡しは、 Event Emitting を利用し、 このように書けます。
components/Child.vue -
20 Vue.jsコミュニティ発のツールチェインについて 1 主要なツール・フレームワーク - Nuxt(https://nuxt.com/)発音記号: /nʌkst/ - Vue.jsを利用したWebフレームワーク -
Vite(https://ja.vitejs.dev/)発音記号: /vit/ - 次世代フロントエンドツール(高速に起動する開発サーバ, 高速なHMR, Rollup互換のプラグインシステム. etc) - Vitest(https://vitest.dev/)発音記号: /vitést/ - フロントエンドのテストフレームワーク - Pinia(https://pinia.vuejs.org/)発音記号: /piːnjʌ/ - TypeScriptフレンドリーな、Vue用の状態管理ツール Vuex正式な後継にあたる -
21 Vue.jsコミュニティ発のツールチェインについて 2 その他ツール - Volar.js(https://volarjs.dev/)発音記号: /bolaɾ/ - VueやAstroなどの組み込み型のフレームワーク用の言語ツール -
vuejs/language-tools(https://github.com/vuejs/language-tools) - Volar.jsベースのVue用の言語ツール群 (vscodeのVue用のextensionsなどでも利用されています) - vue-i18n, eslint-plugin-vue, vuejs/core-vapor .etc 日本人含むアジア圏のメンテナ・コミッタも 数多く携わっていて情報も多い -
22 Vue.jsコミュニティ発のツールチェインについて 3 その他ツール - VitePress(https://vitepress.dev/)発音記号: [vitprés] - ViteとVueによる静的サイトジェネレータ -
VueUse(https://github.com/vueuse/vueuse) - Composablesをまとめたライブラリ - Histoire(https://histoire.dev/)発音記号: [is.twaʁ.] - StorybookのようなVue/Svelte用のUIツール - vue-router(https://router.vuejs.org/) - vue-test-utils(https://test-utils.vuejs.org/) -
23 Vue.jsのTypeScript対応の経緯について 1 Vue2(Options API)の頃は... - Vueコンポーネントのロジックのみを外部ファイルに分割しづらい => mixinという機能はあったが型の恩恵を受けられない... -
状態管理ツールなどから型が渡ってこない => Storeを利用した時点で型の恩恵を受けづらくなる... - thisやテンプレートに型の反映がされない(Props, Emits .etc) => コンポーネント間のデータのやりとりなどが追いづらい... .etc まるっと解決できる 魔法の機能がほしい!! -
25 Vue.jsのTypeScript対応の経緯について 2 Vue.jsのTypeScript対応の過程 1. Composition API の登場 2. コンポーネントランタイムの型付けが改善する
3. Volar.jsとvuejs/language-toolsによりエディタへの型反映の 問題が改善する -
26 Vue.jsのTypeScript対応の経緯について 3 1. Composition APIの登場 - Composition API は
Vueコンポーネントを構成するための 関数ベースのAPIセットの総称 [1] - Reactivity API(ref, computed) - Lifecycle Hooks(onMounted, onUnmounted) - Dependency Injection: 依存性注入(inject, provide) - Vueコンポーネントのロジックのみを外部ファイルに分割しづらい => Composables として切り出すことが可能になり型付けも改善 された [2] [1] https://ja.vuejs.org/guide/extras/composition-api-faq#what-is-composition-api, [2] https://ja.vuejs.org/guide/reusability/composables, -
27 Vue.jsのTypeScript対応の経緯について 4 1. Composition API によるTypeScriptとの親和性の恩恵 - 状態管理用のライブラリなどから型が渡ってこない [1]
https://ja.vuejs.org/guide/extras/composition-api-faq#better-type-inference, [2] https://ja.vuejs.org/guide/typescript/composition-api.html#typing-provide-inject, => Options API 実装当初は型推論の考慮がされておらず、 コンポーネントランタイム と 今まで this で記述していた Reactivity API が紐づいていて柔軟な型付けが困難な状態だった => コンポーネントランタイム から関数ベースのReactivity API が 切り離されることで、カプセル化やモジュール化をしやすくなり TypeScriptフレンドリーに [1] => Provide/Injectなどの状態管理で利用する機能も型の恩恵を受ける ことが可能に [2] -
28 Vue.jsのTypeScript対応の経緯について 5 2. コンポーネントランタイムの型付けが改善される - this(コンポーネントのインスタンス)に型の反映がされない => 型推論付きのヘルパー関数である defineComponent()
が 新たに実装されTypeScriptフレンドリーに [1] => Emitsにも型付けが可能に [2] Propsもユーティリティ型の PropType<T>で型付け可能に [3] [1] https://ja.vuejs.org/api/general#definecomponent [2] https://ja.vuejs.org/api/utility-types#proptype-t [3] https://ja.vuejs.org/guide/typescript/composition-api.html#typing-component-emits, -
31 3. Volar.jsとvuejs/language-toolsの功績 - テンプレートに型の反映がされない [1] Vue Language Server から生まれた
Volar.js と、それが秘める可能性 , mizdra https://speakerdeck.com/mizdra/vue-language-server-karasheng-mareta-volar-dot-js-to-soregami-meruke-neng-xing, Vue.jsのTypeScript対応の経緯について 6 => コンポーネントランタイムのTypeScript対応が終わっても 各エディタの言語ツールにそれらを適用する必要があり、 その問題がVolar.jsベースのlanguage-toolsにより解決される [1] この部分で複雑な問題を抱えていたことで 改善にかなりの時間を要した -
32 - Vue2の頃は、Veturというツールがありましたが、ランタイムの型付け がなされていない問題や様々な問題によりTypeScript対応が未熟だった [1] - Vue.js Language Feature(Volar) 2年を費やし型付けが大きく改善
[2] - Volar のコアが Volar.js に切り出される。同時に Vue固有の実装は vuejs/language-tools へ移動され、IDEでもサポート可能に [3] - Volar.js は Astro や MDX など他の組み込みフレームワークでも利用可能で実 際に利用されている 3. Volar.jsとvuejs/language-toolsの功績の詳細 [1] https://github.com/vuejs/vetur, Vue.jsのTypeScript対応の経緯について 7 [2] Volar New Breaking, Johnson chu https://volarjs.dev/blog/volar-a-new-beginning/, [3] https://marketplace.visualstudio.com/items?itemName=Vue.volar -
33 3. Volar.jsとvuejs/language-toolsの功績の詳細 - vue-tsc を使って確認できる [1] Vue.jsのTypeScript対応の経緯について 8 [1]
https://www.npmjs.com/package/vue-tsc, -
34 3. Volar.jsとvuejs/language-toolsの功績の詳細 - vue-tsc を使って確認できる [1] Vue.jsのTypeScript対応の経緯について 8 [1]
https://www.npmjs.com/package/vue-tsc, -
35 Options API は今後も利用して問題ない - 今まで通りに直感的な開発が可能である - 小中規模アプリケーションでは、Options APIでスピードを持って開発 するような場面が想定される
- 前述した改善により Options API でもある程度の柔軟な型付けが可能 になっている - Vue3 になってからも引き続きOptions APIを利用でき、廃止される予定は ないと明記されている [1] [1] https://vuejs.org/guide/extras/composition-api-faq#will-options-api-be-deprecated Composition API に 引け目を感じなくてもOK!! Vue.jsのTypeScript対応の経緯について 9 -
36 ref: Vue Fes Japan 2023, Evan You キーノート https://www.youtube.com/watch?v=QkhLzoEwvwM
Vue.jsのTypeScript対応の経緯について 追記 Vue.jsは Vue2 からVue3 への 大きな変更による影響を反省し、 今後のマイグレーションを慎重に行っていく -
46 Piniaを利用しよう 利用したい先で、 useCounterStore() を呼び出す。 よしなにカプセル化 されているため、 Store上で定義された countも直接の 書き換えができない
ようになっています。 状態管理と型 4 a pages/index.vue -
47 Piniaを利用しよう 利用したい先で、 useCounterStore() を呼び出す。 よしなにカプセル化 されているため、 Store上で定義された countも直接の 書き換えができない
ようになっています。 状態管理と型 4 a pages/index.vue -
49 状態管理と型 6 TypeScriptフレンドリーに実現する場合 1. SymbolをInjectionKeyとして定義し、定義したSymbolに対して、 ユーティリティ型のInjectionKey<T>を利用し型付けする 2. データを伝搬させたいコンポーネントが含まれている ルートコンポーネントで定義したProvideを呼び出す
(スコープの指定が可能) 3. データが必要なコンポーネント内でInjectionKeyを利用しデータを 取得する -
50 Provide/Injectと型の利用 1. app.vue(Root)などの script内で関数を呼び 出してprovideする 2. データを呼び出したい 先でInjectionKeyを 利用しインジェクション
する 状態管理と型 7 useProviderCounter.ts -
51 Provide/Injectと型の利用 1. app.vue(Root)などの script内で関数を呼び 出してprovideする 2. データを呼び出したい 先でInjectionKeyを 利用しインジェクション
する 状態管理と型 7 useProviderCounter.ts pages/index.vue -
52 Provide/Injectと型の利用 1. app.vue(Root)などの script内で関数を呼び 出してprovideする 2. データを呼び出したい 先でInjectionKeyを 利用しインジェクション
する 状態管理と型 7 useProviderCounter.ts pages/index.vue -
53 型を利用してデータフローを可視化しよう 1 ユーザーデータの取得例で考える 1. IDに紐づくユーザーのデータを取得できるAPIを利用します。 2. APIは、IDとパスワードをPOSTリクエストのボディにセットする 必要があります。 3.
取得したデータは複数のページコンポーネントで利用したいので グローバルステートとして保持する必要があります。 4. 一連のデータフローを型で表現します。 -
63 - Vue.jsのTypeScript対応は複雑な経緯を辿った - Composition APIの登場 - コンポーネントランタイムの型付け - Volar.jsとvuejs/language-toolsの功績
- 具体的な例を通してTypeScriptとの親和性を理解する - 親子コンポーネントとの対話例 - 状態管理の例 - 具体的なユースケースを利用した例 おわりに -
65 Vue.jsのその他資料 Vueコンポーネントのライフサイクルについて - https://ja.vuejs.org/guide/essentials/lifecycle SFC(Single Function Coponent)構文仕様 - https://ja.vuejs.org/api/sfc-spec.html
Composition APIとOptions API どちらを選ぶか - https://ja.vuejs.org/guide/introduction#which-to-choose