はじめに
SpringBootで作ったWebアプリのフロントエンドにVueを導入してみます。
今回やることとして、SpringBootアプリでVueのwelcomeページを動かしてみます。
環境
OS:macOS Ventura 13.6.3
Java:17
SpringBoot:3.2.1
yarn:1.22.21
nodenv:1.4.1
node:16.13.2
vue:2
全体像
springboot-vue(SpringBootプロジェクト)
├── src/main
│ ├── java
│ │ └── com.example.sample(パッケージ)
│ │ ├── Controller.java
│ │ └── Application.java
│ │
│ └── resources
│ ├── static(buildの出力先)
│ │ ├── css
│ │ │ └── app.css
│ │ ├── js
│ │ │ ├── app.js
│ │ │ ├── app.js.map
│ │ │ ├── chunk-vendors.js
│ │ │ └── chunk-vendors.js.map
│ │ │
│ │ └── favicon.ico
│ │
│ ├── templates
│ │ └── index.html
│ │
│ └── application.yml
│
├── vue(vueプロジェクト)
│ ├── node_modules
│ ├── public
│ │ ├──favicon.ico
│ │ └──index.html
│ │
│ ├── src
│ │ ├── assets
│ │ │ └──logo.png
│ │ │
│ │ ├── components
│ │ │ └──HelloWorld.vue
│ │ │
│ │ ├── App.vue
│ │ └── main.js
│ │
│ ├── jsconfig.json
│ ├── package.json
│ ├── vue.config.js
│ └── yarn.lock
│
├── build.gradle
├── gradlew
├── gradlew.bat
└── settings.gradle
SpringBootプロジェクトを作成
まず、spring initializrでSpringBootプロジェクトを作成します。
Dependenciesでは、以下を選択しておきます。
・Thymeleaf
・Spring Web
・Spring Boot Devtools
Controllerを実装
続いて、Controllerを実装します。
実装内容は後述で実装するindex.htmlをテンプレートに指定するだけです。
package com.example.sample;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping
@Controller
public class Controller {
@GetMapping
public String index() {
return "index";
}
}
Thymeleafテンプレートを仮実装
bodyタグ等なく、空で仮実装しておきます。
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
</html>
作成結果
springboot-vue(SpringBootプロジェクト)
├── src/main
│ ├── java
│ │ └── com.example.sample(パッケージ)
│ │ └── Controller.java
│ │
│ └── resources
│ ├── templates
│ │ └── index.html
│ │
│ └── application.yml
│
├── build.gradle
├── gradlew
├── gradlew.bat
└── settings.gradle
vueプロジェクトを作成
続いてSpringBootプロジェクトの中にvueプロジェクトを作成します。
vueプロジェクトの作成は、こちらの記事をベースにします。
springboot-vue $ vue create vue
作成結果
springboot-vue(ルートプロジェクト)
└── vue(vueプロジェクト)
├── node_modules
├── public
│ ├──favicon.ico
│ └──index.html
│
├── src
│ ├── assets
│ │ └──logo.png
│ │
│ ├── components
│ │ └──HelloWorld.vue
│ │
│ ├── App.vue
│ └── main.js
│
├── jsconfig.json
├── package.json
├── vue.config.js
└── yarn.lock
vueの設定変更 & build
buildの出力先を変更
デフォルトのままだと、buildの出力先はvueプロジェクト直下のdistディレクトリとなります。
SpringBootのWebアプリ上で実行させるため、SpringBootプロジェクト内の「resource/static」に変更します。
出力先を変更するには、package.jsonのbuildコマンドに--destオプションを追加して指定します。
{
・・・
"scripts": {
・・・
"build": "vue-cli-service build --dest ../src/main/resources/static/",
・・・
},
キャッシュバスティングをOFFにする
vueのデフォルト設定ではキャッシュバスティングが有効になっており、ファイル名にハッシュ値が付与されてしまいます。
app.js
↓
app.480b8b8a.js
このままでは、build後のJavaScriptファイルをThymeleafテンプレートで指定しづらいです。
そのため、キャッシュバスティングをoffに設定しておきます。
vue.config.jsにfilenameHashingをfalseで設定出来ます。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
filenameHashing: false,
transpileDependencies: true
})
buildを実行
buildの出力先を変更出来たら、buildを実行します。
springboot-vue $ cd vue
vue $ yarn build
「resources/static」内にJavaScript、CSSファイルが出力されていれば成功です。
springboot-vue(SpringBootプロジェクト)
└── src/main
└── resources
└── static(buildの出力先)
├── css
│ └── app.css
└── js
├── app.js
├── app.js.map
├── chunk-vendors.js
└── chunk-vendors.js.map
SpringBootの設定変更
キャッシュバスティングをONにする
vue側でキャッシュバスティングをOFFにした代わりにSpringBoot側でキャッシュバスティングをONに設定します。
spring:
web:
resources:
chain:
strategy:
content:
enabled: true
paths: /**
Thymeleafテンプレートを実装
vueプロジェクト作成時に自動生成されたindex.htmlの内容をThymeleafテンプレートに実装します。
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/favicon.ico">
<title>vue</title>
<script defer="defer" th:src="@{/js/chunk-vendors.js}"></script>
<script defer="defer" th:src="@{/js/app.js}"></script>
<link th:href="@{/css/app.css}" rel="stylesheet">
</head>
<body>
<noscript>
<strong>We're sorry but vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
script、linkタグではbuildで生成したファイルを指定します。
動作確認
Application.javaを実行し、SpringBootアプリを起動します。
ブラウザから http://localhost:8080/ にアクセスし、vueのwelcomeページが表示され、かつブラウザのDevToolsでhtmlを確認し、JavaScript、CSSファイルがキャッシュバスティングされていれば成功です。
参考文献