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