Build, run and deploy Vuejs app with Quarkus

Dmytro Chaban
6 min readMay 4, 2020

--

Many services usually serve some web UI, whether it’s an admin tool, complete portal, or just a single HTML page. Vuejs is a perfect tool that can help you build single-page applications. Why not integrate it tightly with Quarkus?

This article covers:

  1. Setup node and dependencies required for Vuejs
  2. Init basic Vuejs project
  3. Configure Vuejs to serve from Quarkus
  4. Build and watch Vuejs project from maven
  5. Deploy minified Vuejs on maven package

For better UX, please open this article on Quarkify website

Initial setup

Before we can init Vuejs project, we firstly need to install node, npm, vue-cli and probably something more. Feel free to skip this section if you know how to do it, there’s no “quarkus related” magic.

Nodejs and npm

Thank to Nodejs team, they finally made installers that you can use to install both nodejs and npm. Go to https://nodejs.org/en/download/ and download any of your.

Macos and Windows

For macOS and Windows just download the installer and click on it, this part is straightforward. This article doesn’t covers windows though, be ready that code in this article might need some modifications.

Linux

If you’re one of lucky Linux users, you won’t have such luxury as a installer, but it’s not harder then any other installation on this system. Luckly, great developers created cheatsheet on how to install any version of Node.js. We gonna use same 12 version.

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs

Vue CLI

Now we need to install Vue CLI in order to generate initial project, this part is already universal for both platforms

npm install -g @vue/cli

You might need to call it from root user on Linux, so just call sudo npm install -g @vue/cli

After it’s complete, you can call vue --version to verify it's installed properly. We're now ready to init our project.

Init project

We’re now ready to init our project. If you don’t have any Quarkus project to work with, use command below:

mvn io.quarkus:quarkus-maven-plugin:1.4.0.Final:create \
-DprojectGroupId=tech.donau.quarkify \
-DprojectArtifactId=quarkus-vuejs \
-DclassName="tech.donau.quarkify.GreetingResource" \
-Dpath="/hello"
cd quarkus-vuejs

Working example, as always, can be found on our github.

Init Vuejs app

We gonna use POWL, which stands for plain-old webapp location. Not sure if such naming exists, I just made it up. But the idea is to use src/main/webapp location for any ui. This location doesn't have any special features, just a nice location for vuejs sources. You can name it whatever you like. You can name it vue, for example, but in this article we stick to webapp name, and all next code will use this folder.

mkdir src/main/webapp && cd src/main/webapp/
vue create .

When prompted Generate project in current directory? (Y/n) press Y and Enter, then click Enter again for default setup, then just wait a bit before command finishes.

It’s done, you can execute npm run serve and open http://localhost:8080 to check if it's working correctly, press Ctrl+C when done with testing.

Serving from Quarkus

As you know, we have special folder that can serve static files under a root path, it’s src/main/resources/META-INF/resources. Vuejs gives you ability to build and minify your project into few html and js files. So we just need to move those files into resources folder.

We’re not going to move them manually, rather, let’s introduce two more script commands into src/main/webapp/package.json marked bold in next example

"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"watch": "vue-cli-service build --mode=development --watch --dest ../resources/META-INF/resources/",
"prod": "vue-cli-service build --dest ../resources/META-INF/resources/"

},

We introduced two more commands to our arsenal. npm run watch will build our Vuejs project in development mode and put output of the build into our src/main/resourcer/META-INF/resources folder, from where it will be served by Quarkus.

At this stage, if you run npm run watch and ./mvnw quarkus:dev from different terminals, it will already work and you can start modifying both java and javascript code without touching command line anymore, but we can do better than this.

Install, build and watch Vuejs project from maven

We already have a working solution, but won’t it be better to use a single line of code to run both npm run watch and ./mvnw quarkus:dev, and moreover, do this from the root of the project? Currently, you need to go into webapp folder to start our Vuejs project, but it's fixable with some small maven plugins.

Let’s add two more plugins. First, one will help us install Nodejs and npm on the freshly checked out project, install all required dependencies by running npm install and build a production version of Vuejs project.

<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<workingDirectory>${project.basedir}/src/main/webapp</workingDirectory>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v12.16.3</nodeVersion>
<npmVersion>6.14.4</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run prod</arguments>
</configuration>
</execution>
</executions>
</plugin>

This plugin is not just a useless plugin that executes npm install and npm run build for you. It's not even close to this. As I've said, it'll install required version of Nodejs, run all the commands. This is executed on package time and anytime you package your app it will be there for you to ensure you have everything there up to date.

Here’s how bootstrap of a project looks on freshly new Ubuntu instance:

sudo apt-get update
sudo apt-get install -y default-jre
git clone https://github.com/quarkifynet/quarkus-vuejs.git
cd quarkus-vuejs/
./mvnw clean package
java -jar ./target/quarkus-vuejs-0.0.1-runner.jar

We only install default-jre(only for this article, I would go with GraalVM for real projects), clone the project, run package command and execute jar.

So what, you might ask, I use Docker images and Kubernetes to serve my project. But this will come in handy when you change your workbench to some other laptop, or some new developer joins your team that has no prior experience with Nodejs. For them, there’s no change in the workflow at all.

Hope all clear with this plugin, let’s move to second one.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>npm-watch</id>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>npm</executable>
<async>true</async>
<arguments>
<argument>run</argument>
<argument>watch</argument>
</arguments>
<workingDirectory>${basedir}/src/main/webapp</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>

This is more relevant to our development phase than the first one. It will asynchronously execute npm run watch command for us. This plugin, sadly, won't attach to any phase, but we'll need to execute him with our usual command, like this:

./mvnw exec:exec@npm-watch quarkus:dev

The positive side of such separate command would be that you don’t always need to watch webapp classes. If you’re working only on the end you can skip this exec:exec@npm-watch and do only backend changes.

When you execute this line you’ll have both Vuejs and Quarkus up and running.

Real-time code changes

Let’s check how it’s working, execute our maven start script if you haven’t already

./mvnw exec:exec@npm-watch quarkus:dev

Let’s open up http://localhost:8080, you’ll see beautiful Vuejs welcoming page, let’s modify it a little bit.

Go to src/main/webapp/src/App.vue and modify bold code to match your file:

<template>
<div id="app">
<img alt="Quarkify logo" style="background: black; padding: 3vh; border-radius: 1vh" src="https://quarkify.net/wp-content/uploads/2020/05/quarkify_logo_site-1.png">
<HelloWorld msg="Welcome to Your Vue.js App with Quarkus"/>

</div>
</template>

Now, save file and hit Cmd-R in browser to refresh the page, you'll see instant updates to our Vuejs app. Nice!

You can check if Quarkus live reload working by changing GreetingExample.java to return hello2, and then executing http://localhost:8080/hello. There are no changes to Quarkus setup, so it'll work as expected.

In conclusion

This article unleashed basics of how you can speed up your development process, whether you’re Frontend or Backend Engineer. It’s always helpful to have instant feedback. Frontend developers can benefit from having an integrated environment that will work the same in dev and prod. Backend developers can benefit from it by using live reload to e.g catch some bugs. I won’t even say about Full Stack Engineers, because this thing saves hours in the long run.

But I said basics, because there’s more features to grasp from such beautiful integration. In next part of this series, you’ll see how you can speak with the backend without reinventing the wheel.

I’ll leave you with a philosophical question. How many hours have you spent waiting for backend and frontend to rebuild?

Originally published at https://quarkify.net on May 4, 2020.

--

--

Dmytro Chaban

Software Engineer, addicted to productivity and automatization