2022年05月06日

Vue.js v3 + TSX やってみた

こんにちは。すわくんです。

最近は Vue に拘る理由も無くなってきたし、やっぱり React にするかぁ〜と思ったりしていますが、まずは Vue3 を TSX (.tsx) で書いてみようと思いました。 React Hooks と Recoil の勉強から逃げたわけではありますん。

目次
  1. Vite で環境構築する
  2. TSX になって変わること
  3. Vue3 + TSX の所感
  4. あとがき

Vite で環境構築する

ベースは Vite で構築します。
Vue3 を TSX (.tsx) で書くために必要なプラグインは以下の 1 つだけです。

// vite.config.ts
import { defineConfig } from "vite";
import vueJsx from "@vitejs/plugin-vue-jsx";

export default defineConfig({
  plugins: [vueJsx()],
});

TSX で書く

これまで .vue ファイルとして作っていたコンポーネントを、すべて .tsx ファイルとして作っていきます。
VSCode の Volar プラグイン等も必要なく、サクッと書けますね。

setup() 自体は一度だけ実行され、描画関数を戻り値とします。コンポーネントの再描画時には描画関数だけが実行されます。

その他の部分は Composition API を使った一般的な Vue3 のコードと同じです。

// App.tsx
import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const name = ref("John");

    return () => (
      <div>
        <h1>Hello, {name.value}!</h1>
      </div>
    );
  },
});

// main.ts
import { createApp } from "vue";
import App from "./App";

const app = createApp(App);
app.mount("#app");

style ブロックの代替

.tsx で書くことによって、 <style> ブロックは使えなくなりました。
その代替となるものを探さなければいけません。

これらを参考にさせていただきました。
今回はvanilla-extractを使ってみます。

vanilla-extract には Vite 用のプラグインも用意されているので、環境構築は非常に簡単です。
また、 Vue/React 関係なく使えます。

// vite.config.ts
+ import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";

export default defineConfig({
  plugins: [
    vueJsx(),
+   vanillaExtractPlugin()
  ],
});

vanilla-extract については、上記の記事や公式ドキュメント等を参考にしてみてください。

*.css.ts に定義した CSS Modules を import して使います。

// App.tsx
import { defineComponent, ref } from "vue";
import { rootStyle } from "./App.css"; // App.css.ts

export default defineComponent({
  setup() {
    const name = ref("John");

    return () => (
      <div class={rootStyle}>
        <h1>Hello, {name.value}!</h1>
      </div>
    );
  },
});

TSX になって変わること

これらの記事で大体まとめられていますので、参考にしてみてください。

Vue3 + TSX の所感

TypeScript を主眼においたとき敬遠されがちな「Vue っぽさ」がやや薄くなり、コンポーネントの親子間の境界において型検査の恩恵を受けやすくなりました。が、 props, emits, slots まわりなど、まだ少しクセがあるように思います。
ただ、React と比べると「リアクティブシステムの違いに由来するもの」だけが残っている、とも言えるでしょう。

TSX を採用する代わりに、Vue の利点だった「SFC、テンプレート構文、 Scoped CSS」などは失われることになります。
当たり前といえば当たり前ですが、「HTML と CSS を書く」ということを主眼においた体験は無くなります。

また、Vue で TSX を使うというのは「ザ・Vue」でも「ザ・React」でもない中途半端なところであり、使われるケースは少なくドキュメンテーションも多くないため、学習コストの面でもやや不利になる印象があります。(TSX で書くなら React で良くない?ということ)
ただし、既存アプリケーションを Vue から React へ移行するための中間地点としては価値がありそうです。

あとがき

最近ようやく Nuxt3 の RC1RC2 がリリース され、Vue3 の SSR についても環境が整ってきました。
Proxy を使った Vue のリアクティブシステムが個人的には好みで、特に初学者にとってはわかりやすい……と思っています。
が、 TypeScript を主眼においた開発体験を比べると、やはり React に軍配が上がるでしょう。
React やるか。


弊社では「Vue2 アプリケーションの Vue3 化」や「React アプリケーションの新規開発」など、一緒に Web フロントエンドを作っていく仲間を募集しています!


サムネイル左 Vue.js ロゴ (c) Evan You (Licensed under CC BY-NC-SA 4.0)
サムネイル右 TypeScript ロゴ

RELATED POSTS