laravel inertia typescript vue
breezeベースで強化するよ
vue を使うよ
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
バック側は使うライブラリが入ってるっぽい
"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",
フロントは 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"
}
}
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' => [
なんかheaderにLinkを埋め込んでる
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;
};
};
やらないといけないこと
- Front
- js の残骸を ts に
- .editorconfig の調整
- eslint の導入
- unplugin の導入
- scss の導入
- primevue を導入
- pinia を導入
- luxion の導入
- Back
- pint と larastan
- clockwork
- ide-helper
- lang と日本語化
- transaction
- ロガーの調整
- その他
- makefile
- ログイン、アカウント管理システム
- CSV入出力
- Docker
js の残骸を ts に
/js/
で検索して、js を ts に置き換える
.js
で検索して .js を .ts に置き換える
なお、postcssはts化するとめんどいので、jsでだきょうする
vite用にaliasを追加
export default defineConfig({
resolve: {
alias: {
'@': 'resources/ts',
},
},
})
.editorconfig の調整
個人的に js 系は tab2 でお願いしたいので追記
[*.{vue,js,ts}]
indent_size = 2
tab4 と末尾セミコロンがうざいので 先に eslint を調整する
prettier を使わない方針で、eslint-config-standard
をベースにスタイルを整える
vite-plugin-eslint
を使って自動fixを走らせる
typescript は typescript-eslint
を使って lint を行う
このあたりは好み
$ npm install -D eslint eslint-plugin-vue eslint-config-standard @typescript-eslint/parser @typescript-eslint/eslint-plugin vite-plugin-eslint
$ touch ./.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 }
}]
}
}
lint の対象は resources/**/*
とする
全ファイルは遅すぎるので
"scripts": {
"lint": "eslint resources/**/*.{js,ts,vue}"
},
$ npm run lint -- --fix
初回はなんかいか実行すると良い
- type の var は let に
- Ziggyは設定をいじってコマンドを打つ
<?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 で握りつぶす
// eslint-disable-next-line no-undef
.use(ZiggyVue, Ziggy)
- route is not defined
は指定外のglobalの使用禁止のエラーなので、eslintに明示してあげる
"globals": {
"route": true
},
- any は unknown にでもしておく
gitignoreを追加しておく
ziggyはコミットしない
ziggy*
unplugin の導入
自動インポートするマン
$ npm install -D unplugin-auto-import unplugin-vue-components
viteに入れる
ついでに忘れていた vite-plugin-eslint もつっこむ
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',
},
},
})
起動時にファイル生成するので ignore しておく
auto-imports.d.ts
components.d.ts
.eslintrc-auto-import.json
sass を導入する
$ npm install sass
これは <style lang="scss"> とかくだけで使えるお手軽
ui は primevue が tailwind 二対応したので、これを使う
テーマはここから選ぶ
npm install primevue
自動インポートはResolverとやらを使うらしい
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()],
}),
そして app.ts にも組み込む
localeと、pass throughモードを属性マージにする
多分こっちのほうが使いやすい(deepセレクタいらなくなるし)
言語はこっから取ってきて配置する
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)
},
})
tailwindにも組み込む
組み込まないと初期要素としてリセットの対象となって、透明化されるらしい
content: [
'./node_modules/primevue/**/*.{vue,js,ts,jsx,tsx}',
pinia!
npm install pinia pinia-plugin-persistedstate
pinia は useで入れるやつ
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)
},
})
自動化できるけどー必要か?
永続化は入れておく
luxon は個人的あちあち日付ライブラリ
npm install --save luxon
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
}
}
scripts に lint と stan を追加する
"scripts": {
"lint": [
"./vendor/bin/pint"
],
"stan": [
"./vendor/bin/phpstan analyse --memory-limit=2G"
]
},
composer lint
composer stan
clockwork を入れる
すごいべんり
composer require itsgoingd/clockwork
php artisan vendor:publish
> Provider: Clockwork\Support\Laravel\ClockworkServiceProvider を選ぶ
config の enable フラグを、 debug と揃える
'enable' => env('APP_DEBUG', env('CLOCKWORK_ENABLE', null)),
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 に入れる
_ide_helper_models.php
_ide_helper.php
.phpstorm.meta.php
laravel 日本語化する
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'
常時 transaction middleware を入れる
POST, PUT, DELETEのときのみ実行する?
laravel 用のdocker を作る
sail でもいいよ
nginx php-fpm postgresql があればいいかな
nginx unit をちょっと使ってみたい気持ち