In this blog, you will learn how to setup a Maven multi-module project which consists out of a Spring Boot backend and a Vue.js frontend. The application itself will not be created, only the setup of the project is covered in this blog. Enjoy!

1. Introduction

Many applications consist out of a backend and a frontend. But how will you organize and structure your project and how will you deploy the backend and frontend? Many options to choose from and there is no one size fits all. You must make decisions which suit your use case. In either case, it is important to keep the backend code and the frontend code separated from each other. This way, it is easier to change things later on. So, which decisions do you need to make?

  • Do you want to package and deploy the backend and frontend simultaneously?
  • Do you need to be able to scale up and down your application from the beginning?
  • Do you want the frontend to be updated separately from the backend?
  • Etc

There is no right or wrong, you need to choose wisely based on the type of application and non-functional requirements. In this blog, you will learn how to setup the project structure for an application which consists out of a Spring Boot backend part and a Quasar frontend part (Quasar is a Vue.js based framework). Both are packaged in the Spring Boot jar-file and deployed as a single unit. This will enable you to get started quite fast and it will leave the options open to separate both when needed. In the latter case, you will need to deploy the frontend part in a web server like NGINX. As build tool, Maven will be used.

Sources used in this blog are available at GitHub.

2. Prerequisites

Prerequisites needed for this blog are:

  • Basic Spring Boot knowledge;
  • Basic Quasar (Vue.js) knowledge or other frontend framework;
  • Basis Linux knowledge;
  • Basic Maven knowledge.

Besides that, you need to have Java 17 installed, but also Node.js and npm. Instructions for installing Node.js can be found in the official documentation. Choose the instructions for your operating system and ensure that you use a LTS version.

Below the instructions when you are using Ubuntu 22.04.

$ curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - &&\
$ sudo apt-get install -y nodejs

After this, verify the installation:

$ node -v
v18.12.1

Update npm:

$ sudo npm install -g npm@9.2.0

Install the Quasar Framework, which will allow you to create responsive web applications. It is like a layer on top of Vue.js.

$ sudo npm install -g @quasar/cli

3. Project Overview

As written before, you will create a Maven multi-module project which consists out of a Spring Boot backend application and a Quasar frontend. The project structure is the following:

myspringbootvueplanet
├── backend
│   └── pom.xml 
├── frontend
│   └── pom.xml 
└── pom.xml

The main project is called myspringbootvueplanet and has its own pom. It consists out of a module backend and a module frontend, each with their own pom files. In the next sections, this structure will be created and the contents of the directories and pom files will be created.

4. Spring Boot Backend

First, you will start with the Spring Boot backend. Navigate to Spring Initializr, choose Java 17, choose Maven and add the Spring Web dependency. Download the project and unzip it.

Create a directory backend in your main project directory and move the src directory to this new backend directory. Next, copy the pom file to the backend directory.

$ mkdir backend
$ mv src/ backend/src
$ cp pom.xml backend/pom.xml

The pom in the main project needs to be adapted so that it knows about the backend module. Change the contents as follows. Note that the packaging is changed to pom.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	
	<groupId>com.mydeveloperplanet.myspringbootvueplanet</groupId>
	<artifactId>myspringbootvueplanet</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>MySpringBootVuePlanet</name>
	<description>Demo project for Spring Boot with Vue frontend</description>
	<packaging>pom</packaging>

	<modules>
		<module>backend</module>
	</modules>

</project>

The backend pom needs to be changed also. Change the artifactId into backend.

Change the following line:

<artifactId>myspringbootvueplanet</artifactId>

into:

<artifactId>backend</artifactId>

And remove the name tag. The upper part of the pom is the following:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.0.1</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mydeveloperplanet.myspringbootvueplanet</groupId>
<artifactId>backend</artifactId>
<version>0.0.1-SNAPSHOT</version>

Verify whether the Maven project builds by executing the following command from the root of the project.

$ mvn clean verify

5. Quasar Frontend

In order to create a basic Vue.js frontend application with the Quasar Framework, you execute the following command from the root of the repository and you answer the questions according to your needs:

$ npm init quasar
What would you like to build? › App with Quasar CLI, let's go!
Project folder: … frontend
Pick Quasar version: › Quasar v2 (Vue 3 | latest and greatest)
Pick script type: › Typescript
Pick Quasar App CLI variant: › Quasar App CLI with Vite
Package name: … frontend
Project product name: (must start with letter if building mobile apps) … myspringbootvueplanet
Project description: … A demo project for Spring Boot with Vue/Quasar
Author: … mydeveloperplanet <mymail@address.com>
Pick a Vue component style: › Composition API
Pick your CSS preprocessor: › Sass with SCSS syntax
Check the features needed for your project: › ESLint
Pick an ESLint preset: › Prettier
Install project dependencies? (recommended) › Yes, use npm

At this moment, a frontend directory has been created in the root of the repository containing the frontend application. Add the following pom to the frontend directory. In this pom, you make use of the frontend-maven-plugin, which allows you to build the frontend application by means of Maven.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mydeveloperplanet.myspringbootvueplanet</groupId>
  <artifactId>frontend</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>com.github.eirslett</groupId>
        <artifactId>frontend-maven-plugin</artifactId>
        <version>1.12.1</version>
        <executions>
          <execution>
            <id>install node and npm</id>
            <goals>
              <goal>install-node-and-npm</goal>
            </goals>
            <configuration>
              <nodeVersion>v18.12.1</nodeVersion>
            </configuration>
          </execution>
          <execution>
            <id>npm install</id>
            <goals>
              <goal>npm</goal>
            </goals>
            <configuration>
              <arguments>install</arguments>
            </configuration>
          </execution>
          <execution>
            <id>npm install @quasar/cli -g</id>
            <goals>
              <goal>npm</goal>
            </goals>
            <configuration>
              <arguments>install @quasar/cli -g</arguments>
            </configuration>
          </execution>
          <execution>
            <id>npx quasar build</id>
            <goals>
              <goal>npx</goal>
            </goals>
            <configuration>
              <arguments>quasar build</arguments>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

Now add the frontend module to the pom in the root of the repository.

<modules>
  <module>backend</module>
  <module>frontend</module>
</modules>

Verify whether the project builds and execute the following command from the root of the repository:

$ mvn clean verify

6. Combine Backend and Frontend

Now it is time to package the frontend distribution files with the backend application. In order to do so, you add the following to the build-plugins section of the backend pom:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-resources-plugin</artifactId>
      <executions>
        <execution>
	      <id>copy frontend content</id>
	      <phase>generate-resources</phase>
    	  <goals>
	        <goal>copy-resources</goal>
    	  </goals>
	      <configuration>
    	    <outputDirectory>target/classes/static</outputDirectory>
	    	<overwrite>true</overwrite>
    		<resources>
    		  <resource>
	    	    <directory>../frontend/dist/spa</directory>
		      </resource>
    		</resources>
	      </configuration>
    	</execution>
      </executions>
    </plugin>
  </plugins>
</build>

The frontend build outputs the distributable files into directory <root repo>/frontend/dist/spa. The maven-resouces-plugin will copy those resources and wil add them to the <root repo>/target/classes/static directory. The Spring Boot application will serve those pages onto http://localhost:8080/. By default, Spring will serve static content from a number of directories which can be found here. Beware that after this change, you will not be able to run the module builds in parallel anymore because the backend build is dependent of the frontend build. When you are using the Maven daemon to run your builds, you have to add the flag -T1 in order to force it to build sequentially.

Build the application again:

$ mvn clean verify

Start the application from the root of the repository by executing the following command:

$ java -jar backend/target/backend-0.0.1-SNAPSHOT.jar

Navigate in the browser to http://localhost:8080/ and the Quasar Framework start page is shown.

7. Conclusion

In this blog, you learned how to create the project structure for a basic Spring Boot backend with a Quasar frontend application. Deployment is easy because all distributable files are part of the Spring Boot jar-file and can be started by means of a single command.