[laravel8] jetstream なしで vue3 + inertia + tailwindcss を使いたい

# 概要
- 認証は使わないのでjetstreamは要らない
- **でも正直、もうvue3 + inertia + tailwindcssじゃない環境で何一つ書きたくない**

そんなあなたへ。

# インストール

jetstreamを入れた時に使われるものをガシガシ入れていきます

```
composer require inertiajs/inertia-laravel
composer require tightenco/ziggy
```

※`tightenco/ziggy`はVueでroute()を使うのに要ります

```
npm install vue@next
npm install @inertiajs/inertia
npm install @inertiajs/inertia-vue3
npm install @inertiajs/progress
npm install @tailwindcss/forms
npm install @tailwindcss/typography
npm install tailwindcss
npm install postcss
npm install postcss-import
```

# mix設定

`webpack.mix.js` の修正と`webpack.config.js` の設置
（別で作ったjetstream使用プロジェクトから拝借）

```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').vue()
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
    ])
    .webpackConfig(require('./webpack.config'));

if (mix.inProduction()) {
    mix.version();
}

```

```webpack.config.js
const path = require('path');

module.exports = {
    resolve: {
        alias: {
            '@': path.resolve('resources/js'),
        },
    },
};
```
# resource設定

`resources/js/app.js` の修正
`resources/css/app.css` の修正
`resources/views/app.blade.php` （受け皿となるbladeファイル）の設置
（別で作ったjetstream使用プロジェクトから拝借）

```resources/js/app.js
require('./bootstrap');

// Import modules...
import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';

const el = document.getElementById('app');

createApp({
    render: () =>
        h(InertiaApp, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: (name) => require(`./Pages/${name}`).default,
        }),
})
    .mixin({ methods: { route } })
    .use(InertiaPlugin)
    .mount(el);

InertiaProgress.init({ color: '#4B5563' });
```
```resources/css/app.css
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
```
```resources/views/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">
        <meta name="csrf-token" content="{{ csrf_token() }}">

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

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.3/css/all.css">

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

        <!-- Scripts -->
        @routes
        <script src="{{ mix('js/app.js') }}" defer></script>
    </head>
    <body class="font-sans antialiased">
        @inertia
    </body>
</html>
```

# 使ってみましょう

※使用例です

## Controller
```
$ php artisan make:controller TestController
```

```app/Http/Controllers/TestController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Inertia\Inertia;

class TestController extends Controller
{
    public function index()
    {
        return Inertia::render('Tests/Index', [
            'tests' => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
        ]);
    }
}
```

## route
```routes/web.php
Route::get('/test', [App\Http\Controllers\TestController::class, 'index'])->name('test.index');
```

## Vue
```resources/js/Pages/Tests/Index.vue
<template>
  <div class="px-6 py-6 bg-gray-100 md:grid md:grid-cols-3 md:gap-6">

    <div v-for="test in tests" class="mt-5 md:mt-0">
      <div class="px-4 py-5 text-4xl text-center bg-white sm:p-6 shadow rounded-t-md">
        {{ test }}
      </div>

      <div class="flex items-center justify-end px-4 py-3 bg-gray-50 text-right sm:px-6 shadow rounded-b-md">
      </div>
    </div>

  </div>

</template>

<script>
export default {
  props: {
    tests: Object,
  }
}
</script>
```
## 結果
- PC表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108345/763828c4-bd7e-95ec-416a-7c2109f1b920.png)

- SP表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108345/ec86b0bc-f362-c074-69e5-3ed07ccc7a6e.png)

# 諸注意
「自力で何とかした」というよりは
「jetstreamを使ったプロジェクトから必要なものを抜き出した」という感じです。
今後、大元のjetstream側がやり方を変えた場合
上記の方法は古くなってる可能性があるのでご注意を。