LoginSignup
6
4

More than 1 year has passed since last update.

Laravel8 + Vue3 + Typescript + Vuetify で Hello World しただけ

Last updated at Posted at 2022-01-09

はじめに

昨年のQiita記事の投稿数が5しかないという結果を受けてなんとか5を6にしてやろうと書いた記事です。

最近、Laravel8, Vue3, Typescript, Vuetify でアプリを作成したので備忘録として残します。

手順

1. Laravel アプリの作成

curl -s "https://laravel.build/laravel-vue3-typescript-vuetify" | bash

2. docker-compose.ymlを整理

コンテナのビルドに時間かけるの嫌だったので、とりあえずlaravelのコンテナだけにしました。

docker-compose.yml
# For more information: https://laravel.com/docs/sail
version: "3"
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.1
            dockerfile: Dockerfile
            args:
                WWWGROUP: "${WWWGROUP}"
        image: sail-8.1/app
        extra_hosts:
            - "host.docker.internal:host-gateway"
        ports:
            - "${APP_PORT:-80}:80"
        environment:
            WWWUSER: "${WWWUSER}"
            LARAVEL_SAIL: 1
            XDEBUG_MODE: "${SAIL_XDEBUG_MODE:-off}"
            XDEBUG_CONFIG: "${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}"
        volumes:
            - ".:/var/www/html"
        networks:
            - sail
        # depends_on:
        #     - mysql
        #     - redis
        #     - meilisearch
        #     - selenium
    # mysql:
    #     image: 'mysql/mysql-server:8.0'
    #     ports:
    #         - '${FORWARD_DB_PORT:-3306}:3306'
    #     environment:
    #         MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
    #         MYSQL_ROOT_HOST: "%"
    #         MYSQL_DATABASE: '${DB_DATABASE}'
    #         MYSQL_USER: '${DB_USERNAME}'
    #         MYSQL_PASSWORD: '${DB_PASSWORD}'
    #         MYSQL_ALLOW_EMPTY_PASSWORD: 1
    #     volumes:
    #         - 'sailmysql:/var/lib/mysql'
    #     networks:
    #         - sail
    #     healthcheck:
    #         test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
    #         retries: 3
    #         timeout: 5s
    # redis:
    #     image: 'redis:alpine'
    #     ports:
    #         - '${FORWARD_REDIS_PORT:-6379}:6379'
    #     volumes:
    #         - 'sailredis:/data'
    #     networks:
    #         - sail
    #     healthcheck:
    #         test: ["CMD", "redis-cli", "ping"]
    #         retries: 3
    #         timeout: 5s
    # meilisearch:
    #     image: 'getmeili/meilisearch:latest'
    #     platform: linux/x86_64
    #     ports:
    #         - '${FORWARD_MEILISEARCH_PORT:-7700}:7700'
    #     volumes:
    #         - 'sailmeilisearch:/data.ms'
    #     networks:
    #         - sail
    #     healthcheck:
    #         test: ["CMD", "wget", "--no-verbose", "--spider",  "http://localhost:7700/health"]
    #         retries: 3
    #         timeout: 5s
    # mailhog:
    #     image: 'mailhog/mailhog:latest'
    #     ports:
    #         - '${FORWARD_MAILHOG_PORT:-1025}:1025'
    #         - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
    #     networks:
    #         - sail
    # selenium:
    #     image: 'selenium/standalone-chrome'
    #     volumes:
    #         - '/dev/shm:/dev/shm'
    #     networks:
    #         - sail
networks:
    sail:
        driver: bridge
# volumes:
#     sailmysql:
#         driver: local
#     sailredis:
#         driver: local
#     sailmeilisearch:
#         driver: local

3. Sailを使ってローカルで立ち上げ

もし何かエラーでたら、こちらご覧ください。

./vendor/bin/sail up

4. Vue3系の設定

インストール

./vendor/bin/sail npm install vue@next vue-loader@next @vue/compiler-sfc

webpack.mix.js の編集

webpack.mix.js
const mix = require("laravel-mix");

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js("resources/js/app.js", "public/js")
    .postCss("resources/css/app.css", "public/css", [
        //
    ])
    .vue(); //追記

5. コンポーネントの作成

app.blade.php の作成

app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>

<body>
<div id="app"></div>
</body>

</html>

resources/js/components/App.vue
<template>
  <div>{{ message }}</div>
</template>

<script>
import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const message = "Hello World";
    return {
      message
    };
  }
});
</script>

6. ルーティング追加

routes/web.php

Route::get('/app', function () {
    return view('app');
});

7. ビルド

./vendor/bin/sail npm run dev

スクリーンショット 2021-12-31 18.41.32.png

とりあえず Vue3は導入できました。

8. Typescript

インストール

./vendor/bin/sail npm install typescript ts-loader @types/webpack-env -D

app.js を app.tsにファイル名変更

それと同時に、webpack.mix.jsも変更

webpack.mix.js
const mix = require('laravel-mix');
mix.ts('resources/js/app.ts', 'public/js') //mix.jsをmix.tsに、app.jsをapp.tsに変更
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]).vue();

mix.ts に変更できてなかったら、ビルドした際にこんなエラー出るのできちんと変更しましょう。

Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /var/www/html/resources/js/components/App.vue: Unexpected token, expected ","

tsconfig.json作成

tsconfig.json
{
    "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "strict": true,
        "jsx": "preserve",
        "importHelpers": true,
        "moduleResolution": "node",
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "sourceMap": true,
        "baseUrl": ".",
        "typeRoots": ["./resources/js/@types"],
        "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
    },
    "include": [
        "resources/js/**/*.ts",
        "resources/js/**/*.tsx",
        "resources/js/**/*.vue"
    ],
    "exclude": ["node_modules"]
}

9. @types以下の作成

resources/js/@types/shims-vue.d.ts
declare module "*.vue" {
    import {defineComponent} from "vue";
    const component: ReturnType<typeof defineComponent>;
    export default component;
}

10. App.vue 変更

App.vue

<template>
  <div>{{ message }}</div>
</template>


<script lang='ts'> //変更
import { defineComponent, ref } from "vue"; //変更

export default defineComponent({
  setup() {
    const message = ref<string>("Hello World"); //変更
    return {
      message
    };
  }
});
</script>

11. Vuetify の導入

sail npm install vuetify@next -D

app.tsの変更

resources/js/app.ts
import "vuetify/styles";
import { createApp } from "vue";
import { createVuetify } from "vuetify";
import * as components from "vuetify/lib/components";
import * as directives from "vuetify/lib/directives";
import App from "./components/App.vue";

const app = createApp(App);
const vuetify = createVuetify({ components, directives });
app.use(vuetify);
app.mount("#app");

App.vueの変更

resources/js/components/App.vue
<template>
    <v-app>
        <v-card>
            <v-card-title>{{ message }}</v-card-title>
        </v-card>
    </v-app>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
    setup() {
        const message = ref<string>("Hello World");
        return {
            message,
        };
    },
});
</script>

tsconfig.json

tsconfig.json
{
    "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "strict": true,
        "jsx": "preserve",
        "importHelpers": true,
        "moduleResolution": "node",
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "sourceMap": true,
        "baseUrl": "./",
        "typeRoots": ["resources/js/@types"],
        "types": ["vuetify"],  これを追記
        "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
    },
    "include": [
        "resources/js/**/*.ts",
        "resources/js/**/*.tsx",
        "resources/js/**/*.vue"
    ],
    "exclude": ["node_modules"]
}

sail npm run dev

これでいけるはず

スクリーンショット 2022-01-09 12.58.06.png

レポジトリも載せておきます。

おわりに

僕はこれにvue-router を加えて開発しました。

次は nuxt3 x Vuetify3 x Typescript でやってみたいですね。

間違ってるところとか、これ通りにできなければ教えてください。

参考記事

6
4
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
6
4