概要
LaravelとInertia.jsを使えば、フロントエンドとバックエンドをシームレスに連携できます。本記事では、Laravel 11にVue 3とTypeScriptを組み合わせ、効率的なフルスタックアプリケーション開発環境を構築する方法を解説します。Dockerでの環境設定から、初期セットアップのコマンドや設定手順までを網羅します。
目的
この記事の目的は、Laravel 11とInertia.js、Vue 3、TypeScriptを組み合わせて、モダンなフルスタック開発環境を構築することです。
具体的には以下を達成します:
-
バックエンドとフロントエンドの統一
- Laravelの堅牢なバックエンドと、Vue 3のモダンなフロントエンドをInertia.jsでシームレスに連携。
- APIを介さず、シンプルな開発体験を実現。
-
型安全なフロントエンド開発
- TypeScriptを導入し、Vueコンポーネントに型安全性を付与。
- 大規模プロジェクトでもエラーを未然に防ぐ仕組みを構築。
-
モダンな開発体験の提供
- 最新のフロントエンド技術を取り入れることで、開発効率とパフォーマンスを向上。
- Viteを活用した高速なビルドプロセスの導入。
この構築を通じて、チーム全体で統一されたフルスタック環境を実現し、効率的な開発体制を構築します。
前提条件
この記事を進めるにあたり、以下の条件が満たされていることを確認してください:
-
Docker環境の構築が完了していること
- Laravel + Vue3 チーム開発を効率化!統一環境構築と品質向上の完全ガイド
- DockerでPHP 8.4/Nginx + Node 22 + MySQL環境を構築する方法 を参考に、Docker環境が整っていること。
-
プロジェクトのディレクトリ構成が以下のようになっていること
-
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
にリネームしてください。
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
<!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
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SampleController;
Route::get('/sample', [SampleController::class, 'sample']);
rapp/Http/Controllers/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
<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
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
{
"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
<?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:
期待される画面:
まとめ
ここまでで、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のコンポーネント設計に合わせたスタイルの適用方法を実践的に学びます。
これにより、プロジェクト全体で統一感のあるデザインを実現し、効率的なスタイル管理が可能になります。
引き続き良かったら読んでください!