クイック エンジニアリングブログ

株式会社クイック Web事業企画開発本部のエンジニアリングチームが運営する技術ブログです。

ReactとVueを意識せずに両方使えるようにLaravel+Sail+Viteでtsx環境を用意する

ソフトウェアエンジニアの王子です。
ジョジョのアニメを一部から見はじめて現在3部です。 ガォン!

本日はReactとVueを意識せずに使いたいというお話をさせていただきます。

ReactとVueとどっちにするか迷う時があります。

使いやすさだったり、メンバーの習熟度だったりパラメーターは様々ですが

出来上がるものが変わらないのでシステムを利用するお客様の立場からすれば正直「どっちでも良い」話となります。

作る側も「どっちでも良い」と言えるにはどうするかを考えたときに下記のようにVueをReactに寄せていく形で対応してはどうかと思いました。

これでどちらでもeslintや型チェックが同様に利用できれば、あまり違いを意識せずに使えるのではないかと。

ただし、Laravel上でVueをtsxで書けるようにするにはそれなりに環境の整備が必要で、管理も面倒な傾向になります。

楽したい。

そこでLaravel+Sail+Viteの登場です。

dockerコンテナの準備

  • Windows

    • Docker for Desktopをインストール
    • WSL2を有効にして、ストアからubuntuを導入
    • ¥¥wsl$以下のubuntuのフォルダに適当な新規フォルダを作成
  • Mac

    • Docker for macをインストール
    • 適当な新規フォルダを作成

ここ以降は違いがないので、両OS共通です。

Laravel 8.0からsailという開発環境の雛形まで提供されるようになり 環境の構築がとても楽になりました。

# curl -s https://laravel.build/vue_test_blog | bash
# cd vue_test_blog
# alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
# sail up -d

少し時間がかかりますが、これでhttp://localhostへのアクセスにより

f:id:aimstogeek:20210819132127p:plain
laravel初期画面

おなじみ、初期画面が表示されます。

新規フォルダ作成から4ステップでお手軽!

Vite環境の用意

ひとまずBundle方式でない高速のビルドツールと思ってしまえば良いかと。

Laravel-Viteというパッケージがありますのでこちらを利用します。

laravel-vite.innocenzi.dev

以下

  • 導入手順
# sail npx apply laravel:vite --no-ssh
# sail composer update
# sail npm install
  • package.jsonの修正
"scripts": {
    "dev": "vite --host",
    "build": "vite build",
    "serve": "vite preview"
},

※vite.config.tsでも設定できます

  • docker-compose.ymlの修正
ports:
    - '${APP_PORT:-80}:80'
    - '3000:3000'
  • ビルド
# sail php artisan view:clear  #キャッシュが残ってると@viteのディレクティブが動作しない
# sail npm run dev

これでlocalhostにアクセスすると下記の画面が開きます

f:id:aimstogeek:20210819162151p:plain
Vue起動画面

tsxのテスト

ここからは簡単な例でtsxを書きます。

  • main.tsを下記に書き換え
import { createApp } from 'vue'
import { App } from '@/views/App.tsx'

createApp(App).mount('#app')
  • App.vue -> App.tsxに書き換え
import { defineComponent } from 'vue';
import { Block1 } from './components/Block1';

export const App = defineComponent({
  setup() {
    return () => (
      <>
        <Block1 />
      </>
    )
  }
});
import { defineComponent } from 'vue';
import { Block2 } from './Block2';

// この辺でCSS in JSを書く.

export const Block1 = defineComponent({
  name: 'Block1',
  setup() {
    return () => (
      <>
        <Block2
          numberValue={919}
          stringValue={"クイックのブログ"}
        />
      </>
    )
  }
});
import { defineComponent, PropType } from 'vue';

// この辺でCSS in JSを書く.

interface Props {
  numberValue: number;
  stringValue: string;
}
export const Block2 = defineComponent({
  name: 'Block2',
  props: {
    numberValue: {
      type: Number as PropType<Props['numberValue']>,
      default: null,
    },
    stringValue: {
      type: String as PropType<Props['stringValue']>
    }
  },
  setup(props) {
    return () => (
      <>
        <div>== vue with tsx ===</div>
        <div>
          NUMBER VALUE:{props.numberValue}
        </div>
        <div>
          STRING VALUE:{props.stringValue}
        </div>
        <div>================</div>
      </>
    )
  }
});
  • tsxをトランスパイルするためのpluginを追加
# sail npm install @vitejs/plugin-vue-jsx
  • vite.config.tsを修正
import { defineConfig } from "laravel-vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from '@vitejs/plugin-vue-jsx';

export default defineConfig()
    .withPlugin(vue)
    .withPlugin(vueJsx);
  • 再びビルド
# sail npm run dev
  • localhostへのアクセス結果

    f:id:aimstogeek:20210819185620p:plain
    localhostへのアクセス結果

  • propsのリレーで型違反の場合

    f:id:aimstogeek:20210819185649p:plain
    propsのリレーで型違反の場合

最後に

最初はVue3やViteを調べてたのですが、最終的にはSailやtsxなど一通りの記事になってしまいました。

ここまでの準備ステップが少なく、コードスタイルもReactと大きく変わらないため実用の光明が見えつつも、この後ビルドや特定の問題の対処などまだまだ頭を抱える箇所が多そうです。

今回はここまで。

現状の環境準備の手軽さを知れただけでも収穫がありました。 読んで頂き、ありがとうございました!


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! // 919.jp