1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel 11 + Inertia.js + Vue 3 + TypeScriptでモダンなフルスタック環境を構築

Last updated at Posted at 2025-01-04

概要

LaravelとInertia.jsを使えば、フロントエンドとバックエンドをシームレスに連携できます。本記事では、Laravel 11にVue 3とTypeScriptを組み合わせ、効率的なフルスタックアプリケーション開発環境を構築する方法を解説します。Dockerでの環境設定から、初期セットアップのコマンドや設定手順までを網羅します。

目的

この記事の目的は、Laravel 11とInertia.js、Vue 3、TypeScriptを組み合わせて、モダンなフルスタック開発環境を構築することです。
具体的には以下を達成します:

  1. バックエンドとフロントエンドの統一

    • Laravelの堅牢なバックエンドと、Vue 3のモダンなフロントエンドをInertia.jsでシームレスに連携。
    • APIを介さず、シンプルな開発体験を実現。
  2. 型安全なフロントエンド開発

    • TypeScriptを導入し、Vueコンポーネントに型安全性を付与。
    • 大規模プロジェクトでもエラーを未然に防ぐ仕組みを構築。
  3. モダンな開発体験の提供

    • 最新のフロントエンド技術を取り入れることで、開発効率とパフォーマンスを向上。
    • Viteを活用した高速なビルドプロセスの導入。

この構築を通じて、チーム全体で統一されたフルスタック環境を実現し、効率的な開発体制を構築します。

前提条件

この記事を進めるにあたり、以下の条件が満たされていることを確認してください:

  1. Docker環境の構築が完了していること

  2. プロジェクトのディレクトリ構成が以下のようになっていること

    • srcディレクトリが存在し、Dockerコンテナ内でマウントされている。

前回終わり時点のディレクトリの状態

rootdir
  ├─ docker
  │    └─ dockerの設定ファイル構築
  └─ src
       └─ dockerのテスト的なファイルを置いた

具体的な手順

Laravel 11 + Inertia.js + Vue 3 + TypeScriptのフルスタック環境を構築する手順です。

準備

まず、Docker環境を停止し、srcディレクトリを退避させて、新たに空のsrcを作成します。

$ cd docker
$ docker-compose down -v   
$ mv ../src ../src.bk
$ mkdir ../src

作業後のディレクトリ構成は以下のようになります:

rootdir
  ├─ docker
  │    └─ dockerの設定ファイル構築
  ├─ src
  │    └─ 空
  └─ src.bk
       └─ dockerのテスト的なファイルを置いた

バックエンドのセットアップ

コンテナに入る

$ docker-compose up --build -d backend
$ docker exec -it backend-container /bin/bash

Laravelのインストール

以下のコマンドを実行してLaravelをインストールします:

$ composer create-project laravel/laravel .

インストールが完了すると、srcディレクトリの中身が以下のようになります:

src
  ├─ app
  ├─ bootstrap
  ├─ config
  ├─ database
  ├─ lang
  ├─ public
  ├─ resources
  ├─ routes
  ├─ storage
  ├─ tests
  ├─ vendor
  ├─ .env
  ├─ .env.example
  ├─ artisan
  ├─ composer.json
  ├─ composer.lock
  ├─ package.json
  ├─ phpunit.xml
  ├─ README.md
  └─ webpack.mix.js

Inertia.jsのインストール

Inertia.jsをインストールします:

$ composer require inertiajs/inertia-laravel

以下のコマンドでInertia.jsのミドルウェアを作成します:

$ php artisan inertia:middleware

作成されたHandleInertiaRequests.phpを確認します:

$ ls -l app/Http/Middleware/HandleInertiaRequests.php 
-rw-r--r-- 1 root root 894 Dec 29 11:02 app/Http/Middleware/HandleInertiaRequests.php

確認ができたら、コンテナから抜けます:

$ exit

フロントエンドのセットアップ

コンテナに入る

$ docker-compose up --build -d frontend
$ docker exec -it frontend-container /bin/bash

Vue 3とTypeScriptのインストール

以下のコマンドを実行して、Vue 3とTypeScriptをインストールします:

$ npm install @inertiajs/vue3 vue
$ npm install --save-dev typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser vue-tsc @vitejs/plugin-vue vite

インストールされたパッケージを確認します:

$ npm list @inertiajs/vue3 vue
$ npm list --dev typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser 

確認後、コンテナから抜けます:

$ exit

ソースコードの編集

以下のコードをそれぞれのファイルに追加または修正してください:

resources/js/app.ts

以下のコードをresources/js/app.tsに記述してください。
もしapp.jsが既に存在する場合は、app.tsにリネームしてください。

app.ts
import './bootstrap';

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { DefineComponent } from 'vue';

createInertiaApp({
  resolve: (name: string): DefineComponent => {
    const pages = import.meta.glob<DefineComponent>('./Pages/**/*.vue', { eager: true });
    const page = pages[`./Pages/${name}.vue`];
    if (!page) {
      throw new Error(`Page not found: ${name}`);
    }
    return page;
  },
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el);
  },
});

resources/views/app.blade.php

app.blade.php
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Laravel + Inertia</title>
        @vite(['resources/css/app.css', 'resources/js/app.ts'])
    </head>

    <body>
        @inertia
    </body>
</html>

routes/web.php

web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SampleController;

Route::get('/sample', [SampleController::class, 'sample']);

rapp/Http/Controllers/SampleController.php

SampleController.php
<?php

namespace App\Http\Controllers;

use Inertia\Inertia;
use Inertia\Response;
use App\Services\Contracts\SampleServiceInterface;

class SampleController extends Controller
{
    function __construct(
        
    )
    {}

    public function sample(): Response
    {
        $message = "Hello World";
        return Inertia::render('SamplePage', [
            'message' => $message,
        ]);
    }
}

resources/js/Pages/SamplePage.vue

SamplePage.vue
<template>
    <div class="container mt-5">
        <h1 class="text-primary">{{ message }}</h1>
        <button class="btn btn-success" @click="checkType">Click Me</button>
    </div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';

export default defineComponent({
    name: 'SamplePage',
    props: {
        message: {
            type: String as PropType<string>,
            required: true,
        },
    },
    methods: {
        checkType() {
            const value: number = 1;
            console.log(value);
            const unusedVar = 'This is not used';
            console.log(unusedVar);
        },
    },
});
</script>
<style scoped>

</style>

vite.config.ts

vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    logLevel: 'error',
    plugins: [
        vue(),
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.ts',
            ],
            refresh: true,
        }),
    ],
    server: {
        host: '0.0.0.0',
        port: 5173,
        hmr: {
            overlay: true,
        },
    },
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'resources/js'),
        },
    },
});

tsconfig.json

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "strict": true,
    "moduleResolution": "Node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "jsx": "preserve",
    "types": ["vite/client"],
    "baseUrl": ".",
    "paths": {
      "@/*": ["resources/js/*"]
    }
  },
  "include": [
    "resources/**/*.ts",
    "resources/**/*.d.ts",
    "resources/**/*.tsx",
    "resources/**/*.vue"
  ],
  "exclude": ["node_modules"]
}

app/Http/Middleware/HandleInertiaRequests.php

HandleInertiaRequests.php
<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Inertia\Middleware;

class HandleInertiaRequests extends Middleware
{
    /**
     * The root template that's loaded on the first page visit.
     *
     * @see https://inertiajs.com/server-side-setup#root-template
     *
     * @var string
     */
    protected $rootView = 'app';

    /**
     * Determines the current asset version.
     *
     * @see https://inertiajs.com/asset-versioning
     */
    public function version(Request $request): ?string
    {
        return parent::version($request);
    }

    /**
     * Define the props that are shared by default.
     *
     * @see https://inertiajs.com/shared-data
     *
     * @return array<string, mixed>
     */
    public function share(Request $request): array
    {
        return array_merge(parent::share($request), [
            //
        ]);
    }
}

これで環境が整いました!
次はアプリケーションの実行やデバッグに進みます。

確認

フロントエンドの変更を反映させるため、frontend-containerを再起動して動作を確認します。

コンテナの再起動

以下のコマンドでfrontend-containerを再起動します:

$ docker restart frontend-container

動作確認

以下のURLにアクセスして、アプリケーションが正常に動作するか確認してください:

URL:

http://localhost/sample

期待される画面:

以下のような画面が表示されれば成功です:
スクリーンショット 2025-01-04 16.46.39.png

まとめ

ここまでで、Laravel 11とInertia.js、Vue 3、TypeScriptを使ったモダンなフルスタック開発環境を構築しました。この手順を通じて、以下のポイントを押さえることができました:

LaravelとVueの連携

  • Laravelの堅牢なバックエンドと、Vue 3のモダンなフロントエンドをシームレスに統合。
  • Inertia.jsを活用して、APIレスでの効率的な開発を実現。

型安全なフロントエンドの構築

  • TypeScriptを導入し、Vueコンポーネントに型安全性を付与。
  • 大規模なプロジェクトにも対応可能な開発環境を整備。

開発体験の向上

  • Viteを活用して、高速なビルドプロセスと開発サーバーを構築。
  • フロントエンドとバックエンドの変更がリアルタイムに反映される快適な開発環境を提供。

この環境を活用することで、チーム全体で統一された開発フローを確立し、効率的なモダンアプリケーションの構築が可能になります。


次の記事の紹介

ここまでで基盤となるフルスタック環境が整いました。次の記事では、Laravel 11 + Vue 3プロジェクトにSassとBootstrap 5を導入する方法を解説します。

次の記事はこちら

Laravel 11 + Vue 3プロジェクトにSassとBootstrap 5を導入する方法

この記事では、以下のポイントを解説予定です:

  • Bootstrap 5の導入とカスタマイズ
    フロントエンドのUIフレームワークとしてBootstrap 5を導入し、必要に応じたカスタマイズ方法を学びます。

  • Sassによるスタイル管理
    Sassを使用して、効率的でモジュール化されたスタイルの記述方法を解説します。

  • Vueコンポーネントとスタイルの統合
    Vue 3のコンポーネント設計に合わせたスタイルの適用方法を実践的に学びます。

これにより、プロジェクト全体で統一感のあるデザインを実現し、効率的なスタイル管理が可能になります。

引き続き良かったら読んでください!

関連記事

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?