2
4

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 1 year has passed since last update.

SpringBoot上でVueを動かしてみた

Posted at

はじめに

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をテンプレートに指定するだけです。

Controller.java
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タグ等なく、空で仮実装しておきます。

index.html
<!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オプションを追加して指定します。

package.json
{
  ・・・
  "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で設定出来ます。

vue.config.js
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に設定します。

application.yml
spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: /**

Thymeleafテンプレートを実装

vueプロジェクト作成時に自動生成されたindex.htmlの内容をThymeleafテンプレートに実装します。

index.html
<!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ファイルがキャッシュバスティングされていれば成功です。

参考文献

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?