Open38

laravel inertia typescript vue

mbsmbs

breezeを入れて、更に最適化をしていく
工程ごとにcommitしておくと差分がわかりやすいかも

$ composer create-project laravel/laravel laravel10-inertia

$ cd laravel10-inertia
$ composer require laravel/breeze --dev
$ php artisan breeze:install
>  Which Breeze stack would you like to install?
vue
> Would you like any optional features? [None]
typescript
> Which testing framework do you prefer? [PHPUnit]
0      <---- PHPUnit
mbsmbs

バック側は使うライブラリが入ってるっぽい

     "require": {
         "php": "^8.1",
         "guzzlehttp/guzzle": "^7.2",
+        "inertiajs/inertia-laravel": "^0.6.8",
         "laravel/framework": "^10.10",
         "laravel/sanctum": "^3.2",
-        "laravel/tinker": "^2.8"
+        "laravel/tinker": "^2.8",
+        "tightenco/ziggy": "^1.0"
     },
     "require-dev": {
         "fakerphp/faker": "^1.9.1",
+        "laravel/breeze": "^1.24",
         "laravel/pint": "^1.0",
         "laravel/sail": "^1.18",
         "mockery/mockery": "^1.4.4",
mbsmbs

フロントは tailwindcss まで入ってる
@tailwindcss/forms axios がいらないかな

     "type": "module",
     "scripts": {
         "dev": "vite",
-        "build": "vite build"
+        "build": "vue-tsc && vite build"
     },
     "devDependencies": {
+        "@inertiajs/vue3": "^1.0.0",
+        "@tailwindcss/forms": "^0.5.3",
+        "@types/ziggy-js": "^1.3.2",
+        "@vitejs/plugin-vue": "^4.0.0",
+        "autoprefixer": "^10.4.12",
         "axios": "^1.1.2",
         "laravel-vite-plugin": "^0.8.0",
-        "vite": "^4.0.0"
+        "postcss": "^8.4.18",
+        "tailwindcss": "^3.2.1",
+        "typescript": "^5.0.2",
+        "vite": "^4.0.0",
+        "vue": "^3.2.41",
+        "vue-tsc": "^1.2.0"
     }
 }
mbsmbs

AddLinkHeadersForPreloadedAssets とかいうクラスが追加されている

             \Illuminate\View\Middleware\ShareErrorsFromSession::class,
             \App\Http\Middleware\VerifyCsrfToken::class,
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
+            \App\Http\Middleware\HandleInertiaRequests::class,
+            \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
         ],

         'api' => [

https://github.com/laravel/framework/blob/9.x/src/Illuminate/Http/Middleware/AddLinkHeadersForPreloadedAssets.php

なんかheaderにLinkを埋め込んでる

mbsmbs

type 型に色々増えてる

import { PageProps as InertiaPageProps } from '@inertiajs/core';
import { AxiosInstance } from 'axios';
import ziggyRoute, { Config as ZiggyConfig } from 'ziggy-js';
import { PageProps as AppPageProps } from './';

declare global {
    interface Window {
        axios: AxiosInstance;
    }

    var route: typeof ziggyRoute;
    var Ziggy: ZiggyConfig;
}

declare module 'vue' {
    interface ComponentCustomProperties {
        route: typeof ziggyRoute;
    }
}

declare module '@inertiajs/core' {
    interface PageProps extends InertiaPageProps, AppPageProps {}
}

export interface User {
    id: number;
    name: string;
    email: string;
    email_verified_at: string;
}

export type PageProps<T extends Record<string, unknown> = Record<string, unknown>> = T & {
    auth: {
        user: User;
    };
};

mbsmbs

やらないといけないこと

  • Front
    • js の残骸を ts に
    • .editorconfig の調整
    • eslint の導入
    • unplugin の導入
    • scss の導入
    • primevue を導入
    • pinia を導入
    • luxion の導入
  • Back
    • pint と larastan
    • clockwork
    • ide-helper
    • lang と日本語化
    • transaction
    • ロガーの調整
  • その他
    • makefile
    • ログイン、アカウント管理システム
    • CSV入出力
    • Docker
mbsmbs

js の残骸を ts に

/js/ で検索して、js を ts に置き換える
.js で検索して .js を .ts に置き換える

なお、postcssはts化するとめんどいので、jsでだきょうする

vite用にaliasを追加

vite.config.ts
export default defineConfig({
  resolve: {
    alias: {
      '@': 'resources/ts',
    },
  },
})

mbsmbs

.editorconfig の調整

個人的に js 系は tab2 でお願いしたいので追記

.editorconfig
[*.{vue,js,ts}]
indent_size = 2
mbsmbs

tab4 と末尾セミコロンがうざいので 先に eslint を調整する

prettier を使わない方針で、eslint-config-standard をベースにスタイルを整える
vite-plugin-eslint を使って自動fixを走らせる
typescript は typescript-eslint を使って lint を行う

このあたりは好み

https://github.com/standard/eslint-config-standard

https://github.com/gxmari007/vite-plugin-eslint

https://typescript-eslint.io/

$ npm install -D eslint eslint-plugin-vue eslint-config-standard @typescript-eslint/parser @typescript-eslint/eslint-plugin vite-plugin-eslint

$ touch ./.eslintrc.json
.eslintrc.json
{
    "env": {
      "node": true,
      "commonjs": true
    },
    "extends": [
      "eslint:recommended",
      "plugin:@typescript-eslint/recommended",
      "plugin:vue/vue3-recommended",
      "standard"
    ],
    "parserOptions": {
      "parser": "@typescript-eslint/parser",
      "sourceType": "module"
    },
    "rules": {
      // warn rule
      "no-unused-vars": "warn",
      "@typescript-eslint/no-unused-vars": "warn",
      "vue/no-unused-vars": "warn",
      "require-await": "warn",
      "no-unreachable": "warn",

      // ignore rule
      "vue/multi-word-component-names": "off",
      "vue/no-multiple-template-root": "off",
      "vue/no-v-model-argument": "off",

      // prettier rule
      "quotes": ["warn", "single"],
      "comma-dangle": ["warn", "only-multiline"],
      "indent": ["error", 2, { "SwitchCase": 1 }],
      "linebreak-style": ["error", "unix"],
      "semi": ["error", "never"],
      "@typescript-eslint/member-delimiter-style": ["error", {
        "multiline": { "delimiter": "none",  "requireLast": true },
        "singleline": { "delimiter": "comma", "requireLast": false },
        "multilineDetection": "brackets"
      }],
      "vue/max-attributes-per-line": ["error", {
        "singleline": { "max": 5 },
        "multiline": { "max": 1 }
      }]
    }
  }

mbsmbs

lint の対象は resources/**/* とする
全ファイルは遅すぎるので

package.json
    "scripts": {
        "lint": "eslint resources/**/*.{js,ts,vue}"
    },
$ npm run lint -- --fix

初回はなんかいか実行すると良い

mbsmbs
  • type の var は let に
  • Ziggyは設定をいじってコマンドを打つ
config\ziggy.php
<?php

return [

    'output' => [
        'path' => 'resources/ts/ziggy.ts'
    ],
];
$ php artisan ziggy:generate --types

どうやら .ts にすると interface ファイルが生成できるみたい
app.tsを見るとZiggyがundefinedになっているが、これはapp.blade.phpの@routeで挿入されているので、eslint ignore で握りつぶす

resources\ts\app.ts
      // eslint-disable-next-line no-undef
      .use(ZiggyVue, Ziggy)
  • route is not defined

は指定外のglobalの使用禁止のエラーなので、eslintに明示してあげる

    "globals": {
        "route": true
    },
  • any は unknown にでもしておく
mbsmbs

gitignoreを追加しておく
ziggyはコミットしない

resources\ts\.gitignore
ziggy*

mbsmbs

viteに入れる
ついでに忘れていた vite-plugin-eslint もつっこむ

vite.config.ts
import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import vue from '@vitejs/plugin-vue'
import eslint from 'vite-plugin-eslint'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'

const isProd = process.env.NODE_ENV = 'production'
export default defineConfig({
  plugins: [
    laravel({
      input: 'resources/ts/app.ts',
      refresh: true,
    }),

    vue({
      template: {
        transformAssetUrls: {
          base: null,
          includeAbsolute: false,
        },
      },
    }),

    Components({
      dts: 'resources/ts/types/components.d.ts',
      dirs: ['resources/ts/components/**'],
    }),

    AutoImport({
      dts: 'resources/ts/types/auto-imports.d.ts',
      dirs: ['resources/ts/composables/**'],
      imports: ['vue'],
      eslintrc: {
        enabled: true,
      },
    }),

    !isProd && eslint({
      lintOnStart: true,
      include: 'resources/ts/**/*.{js,ts,vue}',
      fix: true,
    }),
  ],

  resolve: {
    alias: {
      '@': 'resources/ts',
    },
  },
})
mbsmbs

起動時にファイル生成するので ignore しておく

.gitignore
auto-imports.d.ts
components.d.ts
.eslintrc-auto-import.json
mbsmbs

sass を導入する

$ npm install sass

これは <style lang="scss"> とかくだけで使えるお手軽

mbsmbs
vite.config.ts
import { PrimeVueResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    vue(),
    Components({
      dts: 'resources/ts/types/components.d.ts',
      dirs: ['resources/ts/components'],
      resolvers: [PrimeVueResolver()],
    }),
mbsmbs

そして app.ts にも組み込む
localeと、pass throughモードを属性マージにする
多分こっちのほうが使いやすい(deepセレクタいらなくなるし)

言語はこっから取ってきて配置する

https://github.com/primefaces/primelocale

app.ts
import PrimeVue from 'primevue/config'
import Tailwind from 'primevue/passthrough/tailwind'
import LocaleJa from './ja.json'

createInertiaApp({
  setup ({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      // eslint-disable-next-line no-undef
      .use(ZiggyVue, Ziggy)
      .use(PrimeVue, { unstyled: true, pt: Tailwind })
      .mount(el)
  },
})

mbsmbs

tailwindにも組み込む
組み込まないと初期要素としてリセットの対象となって、透明化されるらしい

tailwind.config.ts
  content: [
    './node_modules/primevue/**/*.{vue,js,ts,jsx,tsx}',
mbsmbs
npm install pinia pinia-plugin-persistedstate

pinia は useで入れるやつ

app.ts
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

createInertiaApp({
  setup ({ el, App, props, plugin }) {
    const pinia = createPinia()
    pinia.use(piniaPluginPersistedstate)

    createApp({ render: () => h(App, props) })
      .use(pinia)
      .mount(el)
  },
})

mbsmbs

larastan を入れる

https://github.com/nunomaduro/larastan

composer require nunomaduro/larastan --dev

./vendor/bin/phpstan analyse --memory-limit=2G

pint はすでに入ってるみたい
config 作っておく

{
    "preset": "laravel",
    "rules": {
        "no_superfluous_phpdoc_tags": false,
        "phpdoc_separation": false
    }
}
mbsmbs

scripts に lint と stan を追加する

    "scripts": {
        "lint": [
            "./vendor/bin/pint"
        ],
        "stan": [
            "./vendor/bin/phpstan analyse --memory-limit=2G"
        ]
    },
composer lint 
composer stan
mbsmbs

ide-helper を入れる
すごくべんり

https://github.com/barryvdh/laravel-ide-helper

composer require --dev barryvdh/laravel-ide-helper
php artisan ide-helper:generate

php artisan ide-helper:generate
php artisan ide-helper:models --nowrite
php artisan ide-helper:meta

db に繋がってないとエラーなので注意

gitignore に入れる

.gitignore
_ide_helper_models.php
_ide_helper.php
.phpstorm.meta.php
mbsmbs

laravel 日本語化する

https://github.com/Laravel-Lang/lang

composer require laravel-lang/common --dev
php artisan lang:add ja
php artisan lang:update

日本語化していく

config を調整していく

  • app.php
    • 'timezone' => 'Asia/Tokyo'
    • 'locale' => 'ja',
    • 'faker_locale' => 'ja_JP'