Vite + Vue3 + TypeScriptの開発体験
プロジェクトでVue3のアプリケーションを作るかも、、となったので、Vite + Vue3 + TypeScriptで小ネタアプリケーションを書き、フィーリングを掴むことにしました。
Vite
「ゔぃーと」と読むらしいです。20年リリースのフロントエンドのビルドツール。Vueの父が作りましたが、Vueに止まらず、ReactやPreact、Vanilla JS、lit、Svelteのプロジェクトもサポートしたツールです。
ドキュメント曰く
- Rollup.jsをベースにしたビルドコマンドを提供。
- ES modules等、モダンブラウザのパワーを活かして、Devサーバーがサクサクと動く。
- Vueに止まらず、React・Preact・Vanilla JS・lit・Svelteプロジェクトのテンプレート提供。
あたりが持ち味。
Vue3
こちらも20年リリース。私はVue2ととても仲良しだった訳では無い(React・Next.jsで書きがち)のですが、イメージとしては、書きっぷりがスッキリ、かつラフになってきて、かつTypeScriptもサポートと、グッと開発体験を上げてきた、ぐらいなイメージでアプリケーション作りに突入。
TypeScript
AltJS。型やインターフェース、ジェネリック等が効くJavaScript。ここはReactでアプリケーションを書く時からの付き合いなので、今回のキャッチアップの中にはあんまり入らずでした。
とりあえず書くことにした
Viteでプロジェクトテンプレートを作成
ドキュメントに沿って、スタートします。
$ npm init vite@latest
ここからは、表示されるガイドラインに沿って、アプリケーションテンプレートを作ります。今回のテンプレートは vue-ts
で実行。
.
|-- README.md
|-- index.html
|-- package.json
|-- public
| `-- favicon.ico
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- HelloWorld.vue
| |-- env.d.ts
| `-- main.ts
|-- tsconfig.json
`-- vite.config.t
こんなテンプレートが一瞬で出来上がるので、立ち上げ自体もプロジェクトディレクトリ上で npm i
をしてから、npm run dev
で出来る環境になっています。
テンプレート構成について
Viteは vite
コマンドを動作する際、エントリーポイントを index.html
に置きます。そのため、デフォルトでは index.html
がプロジェクトルート直下に配置されています。
Vite は index.html をソースコードとして、またモジュールグラフの一部として扱います。JavaScript のソースコードを参照している <script type="module" src="..."> を解決します。インラインの <script type="module"> や <link href> で参照される CSS も Vite 固有の機能を利用できます。さらに、index.html 内の URL は自動的にリベースされるため、特別な %PUBLIC_URL% プレースホルダは必要ありません。
静的な http サーバと同様に、Vite には、ファイルの提供元となる「ルートディレクトリ」の概念があります。ドキュメントの残りの部分では <root> として示されています。ソースコード内の絶対 URL は、プロジェクトルートをベースとして使って解決されるため、通常の静的ファイルサーバを使用しているかのようにコードを記述できます(より強力な方法を除く)。Vite はルート外のファイルシステムの場所に解決される依存関係を処理することもできるため、モノレポベースの構成でも使用できます。
index.html` を起点に、様々なスクリプトを必要な分だけimportしていく様な挙動をしていく様ですね。他のビルドツールの場合はDevサーバー起動の場合、ページ遷移等のイベント毎にリソースをビルドしてから表示をするので、これに比べてサクサクになる、との理解です。
デフォルトの index.html
では、Vueアプリケーション側のエントリーポイントである main.ts
とつながっているので、HTMLではメタ情報メンテナンスに尽力して、実ページ等は src
配下のVueリソース群を作り込んでいく様な形になります。
npm run dev
する
高速だ!と言われるDevサーバー起動は、大体1秒(1200msぐらい)で完了しました。リソースを足した後でも、立ち上げるのに大体1500ms程。
ここにも書いてあるのですが、依存を精査の上、リソースを生成していた従来のビルドツールに対して、Viteはリクエストに応じたリソース提供をするため、アプリケーションサイズが大きくなっても、「必要分だけリソースを渡す」との役目に徹して、高速さがキープされる具合ですね。
ちなみにホットリロードもとても速い。
Vite では、HMR をネイティブ ESM 上で行います。ファイルが編集されたとき、Vite は編集されたモジュールと最も近い HMR boundary 間のチェーンを厳密に無効化することで(大抵はモジュール本体だけです)、HMR による更新はアプリケーションのサイズに関係なく一貫して高速で実行されます。
待ちのストレスがたちまちに無くなり、とても良いなー、となりました。
Vue3を書く
Vue3でアプリケーションを書きます。Vue2を大して覚えていないので、ギリギリ覚えている箇所だけを取り上げつつ、インパクトが大きかった点を書き落とします。
<script setup>
Vue3の目玉と言われたComposition APIで使える記法。単一ファイルコンポーネントとComposition APIを利用するならば「オススメ」として、本体からも推されています。
- ボイラープレートが少なくて、より簡潔なコード
- 純粋な TypeScript を使ってプロパティと発行されたイベントを宣言する機能
- 実行時のパフォーマンスの向上(テンプレートは中間プロキシなしに同じスコープ内のレンダリング関数にコンパイルされます)
- IDE で型推論のパフォーマンス向上(言語サーバがコードから型を抽出する作業が減ります)
<script setup>
で書かれた内容は、Composition APIの setup()
と同等として実行されます。宣言した変数は <template>
で参照可、何より元々にあったボイラープレートがスッキリ無くなり、めちゃくちゃ普通のJavaScript(TypeScript)の様に処理が書けます。
<script>
とも併用が出来るので、<script setup>
に固執しなくとも、各種シーンに対応が効きそうです。ドキュメントでは inheritAttrs
が例に挙がっていますね。
コンポーネントへのデータバインドが楽に
Vueは、親画面とコンポーネント間の props
と emit
が面倒だったイメージが大きかったのですが、<script setup>
を利用している場合、 v-model
さえ渡してしまえば、暗黙でバインドされる様になっていました。
レンダリング用だけのコンポーネントを作る機会があったので、下記はそれを転用した props
の例です。emit
も defineEmit
で、型定義をしながら実装可能です。
- コンポーネント
<script setup lang="ts">
defineProps<{
hoge: string
}>
</script>
<template>
<div>
<p>{{ hoge }}</p>
</div>
</template>
- コンポーネント登録
import { createApp } from 'vue';
import App from './App.vue';
import SampleComponent from './components/SampleComponents.vue'
createApp(App).component('SampleComponent', SampleComponent).mount("#app");
- コンポーネント利用
<script setup lang="ts">
import { ref } from 'vue';
const hoge = ref('');
</script>
<template>
<div>
<input v-model="hoge" placeholder="書いてくれ!" />
<SampleComponent :hoge="hoge" />
</div>
</template>
<template>
でルートノードが不要に
(惰性で書いてから気付いたのですが)、ルートノードが不要になりました。
<template>
<div>
<p>hoge</p>
<p>fuga</p>
</div>
</template>
が
<template>
<p>hoge</p>
<p>fuga</p>
</template>
ネストが減ってうれしいですね。
まとめ
ドキュメントをちゃんと読みつつ進めないと、、の様なハマりポイントはあったものの、Vite + Vue3 + TypeScriptはとても快適でした。Viteは速い上、Vue3もComposition APIのおかげで、「あれ、どういう構文でプロパティとか書かないとダメだったんだっけ、、」の様な、ボイラープレートを思い出せず辛い、の様なシーンも無くなりました。うれしいですねー。
フレームワークとしての思想の差はあれど、書き味としては、JavaScriptをゴリゴリ書くことで解決出来るシーンが増えたからか、Reactと近くなってきた様なイメージです。紆余曲折を経て、今は、JSXとして全てを関数として取り回しが出来て、hook等うれしいサポートもあるReactの方が好みではあるのですが、Vue3もここまで来ると、書き味としてはもうほとんど好みの問題に収まる気がしてきた、、
ともあれ、Viteも入れてうれしい構成を検討出来るオプションが広がったので、とりあえず私としては、今年は惰性でNext.js!みたいな感じより、もうちょっと幅を広げて色々チャレンジしてみるかー、との結論に落ち着きました。
Discussion