Nuxt.js + SpringBootでSPAを作るための準備

# はじめに
Nuxt.jsでSPAを開発する際にdevサーバ（3000）を起動すると思います。
サーバ側はSpringBoot（8080）で動かしますよね？

開発時は別々のサーバで動かしておく方が何かと都合がいいのです。

ただし、いざ本番にデプロイとなると、SpringBootのプロジェクトにビルドされたSPAのファイル群を同梱する必要があります。SpringBootだと```/src/main/resources/public```、または```/src/main/resources/static```に静的ファイルをおきますよね。

残念ながら、nuxtでビルドして生成されたファイルを上記のパスに置いただけだと、動かないんです。

そこで、Nuxt.jsのSPAをSpringBootで動かすための方法をまとめてみた。

# 準備するもの
- STS
- vue-cli
- npm

STSがない場合は以下のサイトを参照。
[STS4（Spring Tool Suite 4）が出たので環境構築してみた](https://blog.frevo-works.co.jp/entry/2018/09/26/132232)

# SpringBootのアプリケーションを作る

STSでSpringスタータープロジェクトでThymeleafとwebにチェックを入れて作成する。

## 設定
application.ymlに以下の内容を記述する。

```application.yml
spring:
    thymeleaf:
        prefix: classpath:/static/
```

## コントローラクラスの作成
これがないと、画面遷移時に404が発生してしまいます。

```java:RootController.java
package com.springnuxt;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class RootController {
	@GetMapping("/*")
	public String index() {
		return "index";
	}
}
```


# Nuxt.jsでSPAを作る

以下のコマンドでnuxtのプロジェクトを作成する。

```bash
$ cd <上記で作成したプロジェクト>/src/main
$ vue init nuxt-community/starter-template frontend

? Project name frontend
? Project description Nuxt.js project
? Author 

   vue-cli · Generated "frontend".

   To get started:
   
     cd frontend
     npm install # Or yarn
     npm run dev

$ cd frontend
$ npm install

```

SPAでビルドするために、nuxt.config.jsを編集する。

```javascript:nuxt.config.js
module.exports = {
  mode: 'spa', // 追加
  /*
  ** Headers of the page
  */
  head: {
    title: 'frontend',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'Nuxt.js project' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Customize the progress bar color
  */
  loading: { color: '#3B8070' },
  /*
  ** Build configuration
  */
  build: {
    /*
    ** Run ESLint on save
    */
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}
```

nuxtでビルドしたものをspringbootのクラスパス（/src/main/resources/static）にコピーするためのツールをインストールする。

```bash
$ npm install cpx rimraf npm-run-all --save-dev
```

ビルド実行時にコピーするための設定を追加する。

```json:package.json
{
  "name": "frontend",
  "version": "1.0.0",
  "description": "Nuxt.js project",
  "author": "",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint",
    "clean": "rimraf '../resources/static/*'",// 追加
    "copy": "cpx 'dist/**' '../resources/static/'", // 追加
    "pro": "npm-run-all build clean copy" // 追加
  },
  "dependencies": {
    "nuxt": "^2.0.0"
  },
  "devDependencies": {
    "babel-eslint": "^8.2.1",
    "cpx": "^1.5.0",
    "eslint": "^4.15.0",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-loader": "^1.7.1",
    "eslint-plugin-vue": "^4.0.0",
    "npm-run-all": "^4.1.3",
    "rimraf": "^2.6.2"
  }
}
```

画面遷移を確認するために、frontend/pagesにhello.vueを作成する。

```vue:hello.vue
<template>
  <h1>Hello SpringNuxt!</h1>
</template>
```

helloへのリンクを追加する。

```vue:index.vue
<template>
  <section class="container">
    <div>
      <app-logo/>
      <h1 class="title">
        frontend
      </h1>
      <h2 class="subtitle">
        Nuxt.js project
      </h2>
      <div class="links">
        <a
          href="https://nuxtjs.org/"
          target="_blank"
          class="button--green">Documentation</a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey">GitHub</a>
      </div>
      <nuxt-link to="hello">hello</nuxt-link> // 追加
    </div>
  </section>
</template>
```

# 動作確認

```bash
$ cd frontend
$ npm run pro
```
/src/main/resources/staticにファイルが作成されていることを確認し、SpringBootアプリケーションを起動する。起動後、http://localhost:8080/ を開く。

追加したリンクをクリックし、画面遷移することを確認する。

ソース以下にありますので、参考にしてください。
[springnuxt](https://github.com/mr-hisa-child/springnuxt)