🐣

Nuxt.js + LaravelによるSPA開発(リポジトリ分割パターン)

2020/12/29に公開

概要

仕事でNuxtとLaravelでSPAを構築する機会があったため環境構築方法を備忘録として残しておく。

バージョン

  • Nuxt: 2.14.x
  • PHP: 8.0.x
  • Laravel: 8.x
  • PostgreSQL: 12.x

前提

Laravelの公式では認証でSanctumを利用することを勧めていますが、
Multi認証方法が調べてもでてこなかったためSession認証を使って実装する。
Sanctumを利用する場合はこちらの記事を参考にしてください

また、各種Dockerfileの説明は記事の長さの関係上省略してあります。
コードはこちらからご確認ください。
https://github.com/nagi125/sample-spa-nuxt/tree/main/.docker
https://github.com/nagi125/sample-spa-laravel/tree/main/.docker

構成図

Nuxt側設定

完成品

https://github.com/nagi125/sample-spa-nuxt

docker-compose

構成図の左のようにNuxtコンテナだけの構成にしてあります。
Backendとの通信を可能にするためにNetworkをBackendで定義しているsample-spaを利用します。

# docker-compose.yml
version: '3'
services:
  web:
    container_name: sample-spa-nuxt
    build:
      context: ./.docker/web
      dockerfile: Dockerfile
    environment:
      PORT: '3000'
      HOST: '0.0.0.0'
      # axiosで利用するためAPIのOriginを環境変数として持たせておく
      BASE_URL: 'http://nginx'
    ports:
      - 3000:3000
    volumes:
      - .:/app
    stdin_open: true
    tty: true
    restart: always
    networks:
      - sample-spa

networks:
  sample-spa:
    external: true

プロジェクトの作成

環境の立ち上げ

$ docker-compose up

プロジェクトの作成

ファイルが存在するとcurrentにプロジェクトを作成できないため「blog」とする。

$ docker-compose exec web yarn create nuxt-app blog

下記のように誘導されるので必要な項目を入力する(サンプルで載せておきます。)

? Project name: blog
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: Bootstrap Vue
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Testing framework: None
? Rendering mode: Single Page App
? Deployment target: Server (Node.js hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? What is your GitHub username? nagi125
? Version control system: None

🎉  Successfully created project blog

作成したプロジェクトをcurrentに移動させる

$ cp -R blog/. ./
$ rm -r blog

必要なライブラリの追加

認証・APIとの通信に必要なライブラリの追加

$ docker-compose exec web yarn add @nuxtjs/auth @nuxtjs/axios @nuxtjs/proxy

SASSで開発できるようにライブラリを追加

$ docker-compose exec web yarn add --dev sass sass-loader fibers

コンフィグ設定

  • cssはBootstrapVueを利用するためその読み込みと、カスタムcss用にapp.scssを読み込むようにしておきます。
  • moduleは追加したライブラリと作成時に指定したbootstrap-vueを指定します。
  • auth設定についてAPI側の実装方法によって、URLが変わりますので環境に合わせて変更してください。
export default {
  css: [
    '~/node_modules/bootstrap-vue/dist/bootstrap-vue.css',
    { src: '~/assets/scss/app.scss', lang: 'scss'}
  ],
  modules: [
    '@nuxtjs/auth',
    '@nuxtjs/axios',
    '@nuxtjs/proxy',
    'bootstrap-vue/nuxt',
  ],
  axios: {
    proxy: true,
  },
  proxy: {
    '/api/': {
      target: process.env.BASE_URL,
    }
  },
  auth: {
    redirect: {
      login: '/login',
      logout: '/login',
      callback: false,
      home: '/'
    },
    strategies: {
      local: {
        endpoints: {
          login: { url: '/api/admin/auth/login', method: 'post', propertyName: false },
          user: { url: '/api/admin/user', method: 'get', propertyName: false },
          logout: false
        },
        tokenRequired: false,
        tokenType: false,
      }
    },
    localStorage: false,
  },

  router: {
    middleware: ['auth']
  },
}

ログイン画面とテストコード

こちらを記事として書くと、とても長くなってしまうためサンプルコードで確認をおねがいします。

ログインフォーム

https://github.com/nagi125/sample-spa-nuxt/blob/main/pages/login.vue

認証後のサンプルページ

https://github.com/nagi125/sample-spa-nuxt/blob/main/pages/index.vue

Laravel側設定

完成品

https://github.com/nagi125/sample-spa-laravel

docker-compose

構成図の右側のようにNginx + PHP-FPMの構成にしてあります。
またNuxtから直接通信するためにdockerのNetworkを共通の「sample-spa」としています。

# docker-compose.yml
version: '3'
services:
  nginx:
    container_name: sample-spa-nginx
    build:
      context: .docker/nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    volumes:
      - .:/app
    tty: true
    depends_on:
      - api

  api:
    container_name: sample-spa-api
    build:
      context: .docker/api
      dockerfile: Dockerfile
    environment:
      LANG: 'ja_JP.UTF-8'
      TZ: 'Asia/Tokyo'
      APP_NAME: 'Laravel'
      APP_ENV: 'development'
      APP_DEBUG: 'true'
      APP_URL: 'http://localhost'
      LOG_CHANNEL: 'stderr'
      DB_CONNECTION: 'pgsql'
      DB_HOST: 'db'
      DB_PORT: '5432'
      DB_DATABASE: 'laravel_development'
      DB_DATABASE_TEST: 'laravel_testing'
      DB_USERNAME: 'docker'
      DB_PASSWORD: 'docker'
    env_file:
      - .env
    volumes:
      - .:/app
    expose:
      - 9000
    tty: true
    depends_on:
      - db

  db:
    image: postgres:12-alpine
    container_name: sample-spa-db
    environment:
      TZ: 'Asia/Tokyo'
      POSTGRES_USER: 'docker'
      POSTGRES_PASSWORD: 'docker'
      POSTGRES_DB: 'laravel_development'
    volumes:
      - ./.docker/db/data:/var/lib/postgresql/data
      - ./.docker/db/sql:/docker-entrypoint-initdb.d
    ports:
      - 5432:5432

networks:
  default:
    name: sample-spa

Networkの作成

環境を立ち上げる前にNetworkを作れと怒れるはずなので指定した名前のNetworkを作ります。

$ docker network create sample-spa

環境の立ち上げ

$ docker-compose up

プロジェクト作成

ファイルが存在するとcurrentにプロジェクトを作成できないため「blog」とする。

$ docker-compose exec api composer create-project "laravel/laravel=8.*" blog

ファイルを一式currentに移動させる

$ cp -R blog/. ./
$ rm -r blog

Auth関連ファイルのインストール

認証に必要なライブラリを追加する。

docker-compose exec api composer require laravel/ui

CORSの設定

Laravel8ではcorsライブラリがデフォルトで用意されているので、それを利用する。
docker内の通信であるためnuxt側のコンテナ名である「web」を指定する。

// config/cors.php
'allowed_origins' => [
    'http://web',
],

Authの設定

Token認証ではなく、Session認証にするためdriverをsessionに変更する。

// config/auth.php
'api' => [
    'driver' => 'session',
    'provider' => 'users',
],

Middlewareの設定

Session認証とCORSで必要なClassを追加する。

// app/Http/Kernel.php
'api' => [
  \Fruitcake\Cors\HandleCors::class,
  \App\Http\Middleware\EncryptCookies::class,
  \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
  \Illuminate\Session\Middleware\StartSession::class,
  \Illuminate\View\Middleware\ShareErrorsFromSession::class,
],

Seederの準備

ログインと動作確認用にユーザーのseedを作成します。
https://github.com/nagi125/sample-spa-laravel/commit/06231c0193db694f21cd499afc1acdc85c106529
https://github.com/nagi125/sample-spa-laravel/commit/41c2207060ba9c54b306fdcd4a14430f9ca5fba4

コードの準備ができたら下記コマンドでseedを流し込みます。

docker-compose exec api php artisan migrate:refresh --seed

LoginControllerとUserControllerの準備

目的は開発環境の構築なので、ここに関しての解説は省略します。
サンプルを参考にしていただければと思います。

Route

https://github.com/nagi125/sample-spa-laravel/blob/main/routes/api.php

LoginController

https://github.com/nagi125/sample-spa-laravel/blob/main/app/Http/Controllers/Api/Admin/Auth/LoginController.php

UserController

https://github.com/nagi125/sample-spa-laravel/blob/main/app/Http/Controllers/Api/Admin/UserController.php

動作確認

環境立ち上げ

NuxtとLaravelどちらも下記コマンドで環境を立ち上げる

$ docker-compose up

Nuxt側環境立ち上げ

$ docker-compose exec web yarn dev

ログイン画面の動作確認

下記のURLからログイン画面が表示されるか確認する。
http://localhost:3000/login

ログイン後の動作確認

ログイン完了後下記のようなページが表示されれば成功です。

User表示をクリックするとAPIに問い合わせに行き、下記のようにユーザー情報が表示されます。
※ ここに表示されているユーザー名はダミーデータです。

最後に

備忘録なので詳細はGitHub見ろみたいな感じになってしまっていますが、
Nuxt + Laravelの開発環境は以上で作れますのでSPAにチャレンジしてみたいという方に参考になれば幸いです。

Discussion