この記事ではLaravelのフロントエンドをVue+TypeScriptで実装します。
TypeScriptの整形にはESlintを使用します。
使うもの
- Laravel Laravel_Mix
- TypeScript ESlint
- Vue Vue-Router
使わないもの
- TSlint Pretter
環境
- Laravel v7.5
- Node v13
- Vue v2.6
準備
Laravelのプロジェクトを作成
composer create-project --prefer-dist laravel/laravel app
Vueをインストールする
npm i
npm i -D vue vue-router vue-template-compiler
npm i -D typescript ts-loader
npm i -D eslint eslint-plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser
追加・修正するファイル一覧
├---resources
| ├---ts(追加)
| | ├---App.vue
| | ├---app.ts
| | ├---pages
| | | └---index.vue
| | ├---route.ts
| | └---vue-shim.d.ts
| └---views
| └---index.blade.php(追加)
├---routes
| └---web.php(修正)
├---.eslintrc.json(追加)
├---tsconfig.json(追加)
└---webpack.mix.js(修正)
ルートとテンプレートを追加修正
routes/web.php
Route::get('/{any?}', function () {
return view('index');
})->where('any', '.+');
resources/views/index.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">
<title>{{ config('app.name') }}</title>
<!-- Scripts -->
<script src="{{ mix('js/app.js') }}" defer></script>
<!-- Fonts -->
<!-- Styles -->
</head>
<body>
<div id="app"></div>
</body>
</html>
Laravel Mixを修正
webpack.mix.js
const mix = require('laravel-mix')
mix.js('resources/ts/app.ts', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.version().sourceMaps()
mix.webpackConfig({
resolve: {
extensions: ['.vue', '.ts']
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: { appendTsSuffixTo: [/\.vue$/] },
exclude: /node_modules/
}
]
}
})
TypeScriptのソースを追加
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "es2015",
"moduleResolution": "node",
},
"include": [
"./resources/ts/**/*"
]
}
resources/ts/app.ts
import Vue from 'vue'
import router from './router'
import App from './App.vue'
new Vue({
el: '#app',
router,
components: { App },
template: '<App />'
})
resources/ts/App.vue
<template>
<div>
<main>
<div>
<RouterView />
</div>
</main>
</div>
</template>
resources/ts/pages/index.vue
<template>
<h1>Index</h1>
</template>
resources/ts/router.ts
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from './pages/index.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
component: Index
}
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router
resources/ts/vue-shim.d.ts
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
.eslintrc.json
{
"extends": [
"eslint:recommended",
"plugin:vue/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"plugins": [
"vue",
"@typescript-eslint"
],
"env": {
"browser": true,
"es6": true,
"node": true
},
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"rules": {
// タグの最後で改行しないで
"vue/html-closing-bracket-newline": [
2,
{
"multiline": "never"
}
],
// 複数属性を1行に記述
"vue/max-attributes-per-line": "off",
// 不要なカッコは消す
"no-extra-parens": "warn",
// 無駄なスペースは削除
"no-multi-spaces": "error",
// 不要な空白行は削除。2行開けてたらエラー
"no-multiple-empty-lines": [
"error",
{
"max": 1
}
],
// 関数とカッコはあけない(function hoge() {/** */})
"func-call-spacing": [
"error",
"never"
],
// true/falseを無駄に使うな
"no-unneeded-ternary": "error",
// セミコロンは禁止
"semi": [
"error",
"never"
],
// 文字列はシングルクオートのみ
"quotes": [
"error",
"single"
],
// varは禁止
"no-var": "error",
// jsのインデントは2
"indent": [
"error",
2
],
// かっこの中はスペースなし!違和感
"space-in-parens": [
"error",
"never"
],
// コンソールは許可
"no-console": "off",
// カンマの前後にスペース入れる?
"comma-spacing": "error",
// 配列のindexには空白入れるな(hogehoge[ x ])
"computed-property-spacing": "error",
// キー
"key-spacing": "error",
// キーワードの前後には適切なスペースを
"keyword-spacing": "error"
}
}
これで下のコマンドでビルドできる
npm run dev
npm run watch
npm run prod
※もしcross-envでエラーが出たらグローバルインストールする
npm i -g cross-env
後はIDE毎にESLintでTypeScriptの整形を行うよう設定する。
ちなみにVS-Codeであれば
参考
https://www.hypertextcandy.com/vue-laravel-tutorial-introduction
https://megu-tech.hatenablog.com/entry/2019/08/02/154710
https://qiita.com/Naturalclar/items/21ca036339f8ef48e777