Build, run and deploy Vuejs app with Quarkus
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:
- Setup node and dependencies required for Vuejs
- Init basic Vuejs project
- Configure Vuejs to serve from Quarkus
- Build and watch Vuejs project from maven
- 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.