LoginSignup
0
0

More than 1 year has passed since last update.

laravel9.x inertia vue3.2 のsetuplang="ts"するとUnexpected token, expected ","エラーになる場合の対処

Last updated at Posted at 2022-09-07

laravel9 + inertia + vue3.2
@inertiajs/inertia-vue3@0.6.0
@inertiajs/inertia@0.11.0
@inertiajs/progress@0.2.7

上記環境でサンプルサイトのコードを試していたら
vue3.2からの新機能の<script setup>でコードを記述の後に
lang="ts"をつけて<script setup lang="ts">にしてビルドしたところ
以下のエラーがでるようになる。

  Compiled with some errors in 12.82s

ERROR in ./resources/js/Pages/Hoge/Show.vue?vue&type=template&id=ad2814ac&ts=true (./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/Pages/Hoge/Show.vue?vue&type=template&id=ad2814ac&ts=true)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /var/www/html/laravel9vue3/resources/js/Pages/Hoge/Show.vue: Unexpected token, expected "," (8:27)

typescriptの構文エラーとbabel-loaderでのビルドエラーっぽいのでそれらしいメッセージでググってみたがこれといった解決方法が載っていない。
とりあえずビルドが通すまでの手順をメモる。

ncu(npm check update)で最新パッケージにしておく

npm-check-updatesはグローバルに入れておく。

# npm install -g npm-check-updates

ドキュメントのベースフォルダでncuコマンドを実行してアップデートが出ないようにしておく

$ ncu
Checking /var/www/html/hogehoge/package.json
[====================] 39/39 100%

All dependencies match the latest package versions :)

webpack.mix.jsをtypescript対応にする。

webpack.mix.js
mix.ts('resources/js/app.ts', 'public/js')
    .vue()
    .postCss('resources/css/tailwind.css', 'public/css', [require('tailwindcss'), require('autoprefixer')])
    .sass('resources/scss/bootstrap.scss', 'public/css')
    .alias({
        '@': 'resources/js',
    })
    .sourceMaps();

お試しでいろいろ付随しているが変えるところは
mix.js(の所をmix.ts(に変更
resources/js/app.jsresources/js/app.tsにリネーム
の2か所。

app.ts(もとはapp.js)の修正

inertia+vueでのapp.jsのサンプルなどでよく見る設定だが以下のように変更

resources/js/app.ts
import './bootstrap';
//import '../css/app.css';

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { createI18n } from 'vue-i18n';
import route from 'ziggy-js';
import 'flowbite';

//import "bootstrap/dist/css/bootstrap.min.css";
//import "bootstrap";

const appName = window.document.getElementsByTagName('title')[0]?.innerText || '';

async function loadLocaleMessages(i18n, locale){
    const messages = await require(`../../lang/${locale}.json`);
    i18n.global.setLocaleMessage(locale, messages)
}

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({ el, app, props, plugin }) {
        const setupAsync = async ({ el, app, props, plugin }) => {
            const i18n = createI18n({
                legacy: false,
                globalInjection: true,
                locale: 'ja'
            });
            await loadLocaleMessages(i18n, 'ja');

            createApp({ render: () => h(app, props) })
                .use(plugin)
                .use(i18n)
                .mixin({ methods: { route } })
                .mount(el);
        }
        setupAsync({ el, app, props, plugin });
    },
});
InertiaProgress.init({ color: '#4B5563' });

こちらもお試しでいろいろソースコードが変わっているが変更点としては以下の点。
import route from 'ziggy-js';を明記してroute変数を使えるようにする。
こちらがないとcreateAppのmixinのところでエラーとなる。

・createInertiaApp関数のsetupメソッド内で非同期処理を行うように変更
vue-i18nによる多言語化も試していたため発生。サンプルサイトだと
setupメソッド自体をasyncをつけて非同期化するのだがどうもうまくいかないので
setupAsyncというラッパー関数を作って対応

これでvueファイル内の<script setup lang="ts">としてもエラーにならなくなった。

追記
vue3でtypescript化するためファイルshims-vue.d.ts/resources/js/@types/配下に格納する。

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

tsconfig.jsontypeRootsを設定する。

tsconfig.json
...(略)...
    "typeRoots": [
        "node_modules/@types",
        "resources/js/@types"
    ],
...(略)...

多言語化の対応(未)

app.blade.php

<script>
var __locale = '{{ app()->getLocale() }}'
</script>

としてこの__locale変数をapp.jsで使って多言語化する方法があるが
typescript化にすると使えないので、とりあえずapp.tsでは'ja'固定にしている。
laravelの外部定義は別の方法でjsに取り入れたほうがいいのかも。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0