Build, run and deploy React app with Quarkus

Dmytro Chaban
Quarkify
Published in
5 min readMay 26, 2020

If your project needs UI, React probably is a good option for any middle-size service. With Quarkus, it’s super easy to serve your React app.

This article covers:

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

For a better experience, go to Quarkify website

Initial setup

In order to React with JSX and other features, we’ll need to install node, npm, and create-react-app. Feel free to skip this section if you already have it.

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 an installer, but it’s not harder then any other installation on this system. Luckily, great developers created cheatsheet on how to install any version of Node.js. We gonna use the same 12 version.

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

create-react-app

In our Vuejs article, we had to install additional global dependency to init the project. For react, we can use npx create-react-app to init the 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.1.Final:create \
-DprojectGroupId=tech.donau.quarkify \
-DprojectArtifactId=quarkus-react \
-DclassName="tech.donau.quarkify.GreetingResource" \
-Dpath="/hello"
cd quarkus-react

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

Init React app

For location of our React app, we gonna use /src/main/webapp folder as a root folder. This is just helpful location to organize your sources neatly.

mkdir src/main/webapp && cd src/main/webapp/
npx create-react-app .

This command will init the basic React project with initial structure and simple view.

Now you can run npm start and open http://localhost:3000. You should see a familiar atom image. When finished, press Ctrl+C, because we're moving from atoms to quarks 🙂

Serving from Quarkus

Quarkus has dedicated folder that’s already prepared to serve static files, it’s src/main/resources/META-INF/resources. We only need to build or React project into this folder.

We can, of course, move them manually, but we have a good command that helps us put files automatically to the required folder.

Let’s open src/main/webapp/package.json and put one additional lines into scripts closure

"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"prod": "react-scripts build --dest && mv build/* ../resources/META-INF/resources"

},

If you read our Vuejs guide, you could notice that we don’t have a watch command. And that is because react-scripts doesn’t think that it’s a good way of doing it. In other words, either you serve or build a single time. If you really need it, have a look at this answer.

You can run npm run prod in a webapp folder and ./mvnw quarkus:dev afterwards, and you'll already see that Quarkus serves our static website.

Install and build React project from maven

Let’s use Maven to do all the node and npm installation boilerplate. Firstly, let’s make so when we checkout our project, maven will install NodeJs and build the 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 the 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-react.git
cd quarkus-react/
./mvnw clean package
java -jar ./target/quarkus-react-0.0.1-runner.jar

React development mode

So what I do with React projects is that I run npm start in one terminal window, and ./mvnw quarkus:dev in second. Jhipster with Quarkus and React works the same way, so to speak.

Let’s modify our React page a little bit. Go to http://localhost:3000 and look at the initial page

Open up webapp/src/App.js and replace bold text in your file to match next:

import React from 'react';
import './App.css';

function App() {
return (
<div className="App">
<header className="App-header">
<img src="https://quarkify.net/wp-content/uploads/2020/05/quarkify_logo.png" className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
...

Go back to browser, you’ll see instant change:

In the next chapter of React with Quarkus, we’ll see how to communicate effectively with your frontend during the development phase, but if you decide to hack around the current setup, I suggest you add CORS property into application.properties file. This way your React app will be able to communicate from port 3000 to our Quarkus app on port 8080

quarkus.http.cors=true

Serving React app from Quarkus

Once you done development, just run ./mvnw clean package and you'll have ready jar with all the required static files.

./mvnw clean package

To check if it’s correct, you can execute next command and open http://localhost:8080

java -jar ./target/quarkus-react-0.0.1-runner.jar

And, as expected, you’ll see updated React page served from 8080 port.

In conclusion

You now know how easy it is to build the React app and serve it from the Quarkus application. There’s more to learn. The next step is to connect our React application with Quarkus API, without writing fetch logic for each of the requests. This is the topic for the next article 🙂

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

--

--

Dmytro Chaban
Quarkify

Software Engineer, addicted to productivity and automatization