LoginSignup
3
4

More than 3 years have passed since last update.

LaravelとVueでSPAを作るときにTypescriptとpugを使う設定をする

Last updated at Posted at 2020-05-14

LaravelVue.jsTypescriptpugSPAを作ったときのメモ。

docker --version
Docker version 19.03.8, build afacb8b

扱ったDockerのバージョンは19.03.8。

Fig.1
project
├── db
├── web
├── Dockerfile
├── docker-compose.yml
└── .env

以下の手順で Fig.1 のような構成のレポジトリを作り、webディレクトリの中にLaravelをインストールする。

レポジトリと各ファイルを作成

mkdir project_name && cd $_ && touch {docker-compose.yml,Dockerfile,.env}

プロジェクトのディレクトリを作成し( mkdir project_name )、作成したディレクトリに移動し( cd $_ ) 1docker-compose.yml, Dockerfile, .env ファイルを作成する( touch {docker-compose.yml,Dockerfile,.env} )。

この時点で Fig.2 の構成になる。

Fig.2
project_name
├── Dockerfile
├── docker-compose.yml
└── .env

各ファイルは以下の内容で書く。

docker-compose.yml

docker-compose.yml
version: '3'
services:
  web:
    build: .
    container_name: ${PROJECT}-web
    ports:
      - 80:80
      - 3000:3000
    volumes:
      - ./web:/var/www/html/${PROJECT}
    depends_on:
      - db
  db:
    image: mysql:8
    container_name: ${PROJECT}-mysql
    restart: always
    environment:
      MYSQL_DATABASE: ${PROJECT}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      TZ: ${TZ}
    ports:
      - 3306:3306
    volumes:
      - ./db:/var/lib/mysql

Dockerfile

Dockerfile
FROM php:7.4-fpm

COPY --from=node:12
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update \
  && apt-get install -y wget git zip unzip vim libpq-dev \
  && : 'Install PHP Extensions' \
  && docker-php-ext-install pdo_mysql pdo_pgsql \

WORKDIR /var/www/html/project_name

マルチステージビルド2Node.jsComposerDocker公式イメージ を利用する。

.env

.env
PROJECT=project_name
DB_USER=user_name
DB_PASSWORD=password
TZ=Asia/Tokyo

コンテナを起動

docker-compose up -d

この時点で Fig.1 の構成になる。

コンテナに入る

docker-compose exec web bash

コンテナの中ではcomposernpmが使える。

# composer --version
Composer version 1.10.6 2020-05-06 10:28:10

# node --version
v12.16.3

# npm --version
6.14.5

Laravelをインストール

# composer create-project --prefer-dist laravel/laravel .

// バージョンを指定する場合 (e.g. Laravel6 を指定する場合)
# composer create-project --prefer-dist laravel/laravel . "6.*"

Laravelの設定

web/config/app.php

app.php
<?php

return [

    // 他の設定

    'timezone' => 'Asia/Tokyo',
    'locale' => 'ja',

    // 他の設定
];

設定値を変更。

web/.env

.env
// 他の設定
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=project_name
DB_USERNAME=user_name
DB_PASSWORD=password
// 他の設定

データベースに接続するための情報を入れる。
MySQLに接続する場合はDB_CONNECTION=mysql
DB_HOSTdocker-compose.ymlservicesで設定したdbとする。
他の設定も .env で設定したものと同じ。

パッケージをインストール

# npm i
# npm i vue vue-router pug pug-plain-loader --save-dev  
# npm i -g typescript
# tsc --init

typescriptをグローバルにインストールするとtscコマンドが使えるようになり、

# tsc --version
Version 3.8.3

tsc --initとするとtsconfig.jsonが生成される。3
tsc --initgit init と混同して tsc init としないように注意。4

ファイルを編集

web/webpack.mix.js

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 application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix
.webpackConfig({
  module: {
    rules: [{
      test: /\.pug$/,
      oneOf: [
        {
          resourceQuery: /^\?vue/,
          use: ['pug-plain-loader']
        },
        {
          use: ['raw-loader', 'pug-plain-loader']
        }
      ]
    }]
  }
})
.browserSync({
  proxy: '0.0.0.0:80',
  open: false,
  files: [
    'resources/**/*',
    'public/**/*'
  ]
})
.ts('resources/ts/app.ts', 'public/js/app.js')
.sass('resources/sass/app.scss', 'public/css')
.version()

pugを扱うための設定も記載する。5
BrowserSyncの設定を記入。6 7
mix.js() と書かれていた部分を mix.ts() 変えるだけ。8 あとは扱うファイルの変更に従って引数のファイルもjsからtsに変更する。

web/resources/ts/app.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 />'
})

web/resources/js/app.jsweb/resources/ts/app.ts に書き換える。
ここで App.vuerouter.ts を読み込む。

web/resources/ts/App.vue

App.vue
<template lang="pug">
div
  main
    RouterView
</template>

ルートコンポーネント。
ここで Vue Router が提供する RouterView9 を使う。

web/resources/ts/router.ts

router.ts
import Vue from 'vue'
import VueRouter from 'vue-router'
import Foo from './pages/Foo.vue'
import Bar from './pages/Bar.vue'

Vue.use(VueRouter)

const routes: any = [{
    path: '/foo',
    component: Foo
  },
  {
    path: '/bar',
    component: Bar
  }
}]

const router = new VueRouter({
  mode: 'history',
  routes
})

export default router

ルーティングの定義の設定。
History モード 10にすることでURLがハッシュなしで設定できる。

web/resources/ts/pages/Foo.vue

Foo.vue
<template lang="pug">
  .foo
    h1 Foo
</template>

web/resources/ts/pages/Bar.vue

Bar.vue
<template lang="pug">
  .bar
    h1 Bar
</template>

web/routes/web.php

web.php
<?php

Route::get('/{any?}', function () {
    return view('index');
})->where('any', '.+');

web/resources/views/index.blade.php

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>project_name</title>
    <script src="{{ mix('js/app.js') }}" defer></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

web/vue-shim.d.ts

vue-shim.d.ts
declare module "*.vue" {
    import Vue from "vue";
    export default Vue;
}

Typescript: IDE reports TS2307: Cannot find module error for Vue components imports とエラーが出たので作成する。11

サーバーを起動

# php artisan serve --host 0.0.0.0 --port 80

ビルド

# npm run watch-poll

http://localhost:3000 にアクセスしてブラウザで確認する。

参考

3
4
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
3
4