LaravelでTypeScript + Vue 3を導入する方法


目的

LaravelでVueを導入する場合、従来だとlaravel/ui → php artisan ui vueで立ち上げる流れですが、
このパッケージがてVue 2をデフォルトで入れてくるので、Vue 3のCompositional APIでTypeScriptを使った開発がしたい人(著作者)には何だか粋じゃない感じがします。

ので、LaravelでTypeScript + Vue 3を使う方法を解説します!

まずはVue.jsを

  1. laravelプロジェクトのRoot Directoryにcdして
  2. npm install vue@next vue-loader@next @vue/compiler-sfcでVue関連のNPMパッケージをDevにインストール
package.json
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@vue/compiler-sfc": "^3.2.23",
        "axios": "^0.21",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "vue": "^3.2.23",
        "vue-loader": "^16.8.3"
    }
}

  1. resources/js/componentsのフォルダーを作り、そこにApp.vueとかお好きなComponent名を作る
  2. webpack.mix.jsのSCSSのレンダーの後に、.vue()を実行する。これはWebpackに.vueのモジュールのCompilingを可能にしてくれる機能です。
webpack.mix.js
const mix = require('laravel-mix');

mix.js('resources/js/app.ts', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]).vue();


  1. resources/js/app.jsを編集し添付写真のようにcreateAppでVueを起動させる
app.js

import { createApp } from "vue";
import App from "./components/App.vue";

const app = createApp(App);

app.mount("#vue-app");
  1. npm install && npm run devでWebpackにCompileをさせます。

要注意!
<script>タグでapp.jsを読み込むが、HTMLのdivの後にしないとHMTLがレンダーされる前に実行され、Vueがタグを見つけられないというエラーを出します

ここまででJavaScriptのみのVue 3のセットアップが終わります。

TypeScriptを導入

まず大胆に、resoucres/js/app.jsの拡張を.tsに変更します。

resources/js/app.ts
import { createApp } from "vue";
import App from "./components/App.vue";

const app = createApp(App);

app.mount("#vue-app");

そしてwebpack.mix.jsでJavaScriptのCompilerからTypeScriptのCompilerに変更します。
また、'resources/js/app.js'を'resources/js/app.ts'に。

webpack.mix.js

const mix = require('laravel-mix');
mix.ts('resources/js/app.ts', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]).vue();

npm install typescript -Dを実行すると、自動でts-loaderも入るはず。
出なければ npm install ts-loaderで追加。
-Dのオプションは--save-devと一緒。Vueも含め、Webpack MixがCompileしてくれるので、DevのDependenciesで十分。

package.json
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@vue/compiler-sfc": "^3.2.23",
        "axios": "^0.21",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "ts-loader": "^9.2.6",
        "typescript": "^4.5.2",
        "vue": "^3.2.23",
        "vue-loader": "^16.8.3"
    }
}


./にtsconfig.jsonを追加します。Vueの標準設定でいいが、念のために'resources/js/*/'を追加することで全ての.tsファイルをCompileしてよーということになるので、しておいた方がいいと思われます。

tsconfig.json

{
    "compilerOptions": {
        "target": "ES2015",
        "module": "ES2015",
        "strict": true,
        "jsx": "preserve",
        "moduleResolution": "node",
    },
    "include": ["./resources/js/**/*"]
}


問題発生:.vueのモジュールのTypeを指定しないとエラーになるど!

なので、上記のtsconfigにまずtypeRootsの設定でTypeを自動で読み込むフォルダーの場所を指定しましょう。

tsconfig.json

{
    "compilerOptions": {
        "target": "ES2015",
        "module": "ES2015",
        "strict": true,
        "jsx": "preserve",
        "moduleResolution": "node",

        "typeRoots": ["./resources/js/@types"]

    },
    "include": ["./resources/js/**/*"]
}


そして'./resources/js/'のところに'@types'というフォルダーを作って、shims-vue.d.tsというファイルを入れます。
名前についてですが、任意かと思うのですが、Vue.jsのTypeScriptのDocumentsでは上記の名前にしているので、それに合わせて命名しましょう。

./resources/js/@types/shim-vue.d.ts

declare module "*.vue" {
    import type { DefineComponent } from "vue";
    const component: DefineComponent<{}, {}, any>;
    export default component;
}


上記の設定でTypeScriptに.vueのモジュールのTypeを教えているのです。

最後に、npm install && npm run devであちこーこーのTypeScript + Vueのアプリが出来上がります!