0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel + Vue + TypeScript + Eslint

Posted at

この記事では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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?