Today we tackle a common task that every programmer will face at least one time in his career: create a Graphic User Interface (GUI).
In the last months, my team faced the urgent task of creating a GUI for our project only for presentation reasons.
It was urgent because until that moment the analysis and presentation were done checking the Database records and in a month an important demo with the project had to be run
We decided to create the GUI in such a short time, and our first idea was to create a new module in ReactJS (our official Javascript framework in the company)
After further analyzing, we calculated that we would have to wait for machines, namespaces, and a lot of bureaucratic stuff to put the GUI at work.
We were a little worried because we could not afford to spend this time, create a new module from scratch could be very time-consuming considering that our experience with React was more from our projects and interests, so we had to use what we had: a Maven project based on Kotlin.
(This is one of the possible solutions to create a new module in JavascripXXKt and display it in a Spring-based application. The JS module can contain React or Angular, or whichever JS framework the user wants)
In this article, I will show the adopted solution with a simple application as an example. The project we consider in this example contains:
- a wrapper module called
project-test
- a module
application
that contains the application we want to launch - the
gui-test
module that we use for storing the GUI
Inside the gui-test maven module we created a new react app using Create React App, a tool provided by Facebook to quickly set up an already configured basic React app. Below you can find the command we launched:
npx create-react-app
The next step is to change the pom.xml
file inside gui-test
so that we can execute npm commands (a free NodeJS package manager) during the build of the entire project.
For our goal we leverage frontend-maven-plugin, adding it inside the build section of the pom file
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.12.0
</version> <!-- this field contains the version of the plugin, at the moment the LATEST is 1.12.0 -->
<configuration>
<nodeVersion>14.17.4
</nodeVersion> <!-- this field contains the version of NodeJS that will be used for building, here I used the latest Long-Term Support -->
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
As shown in the snippet above, we created two execution steps: the first one downloads and install node and npm (useful in CI environment for retrieving them if not installed on the machine), the second one launches npm install
to install the needed dependencies, and the third one build the app with the npm build
command.
For last, we need to save the generated JS files inside the module that creates the final jar of the application (in our example the application
module).
The idea is to copy the built JS files from the gui-test
module to the static folder of the generated classes so that when the final jar will be assembled, Spring Boot will automatically add the JS files to the static web resources that are served by Tomcat server.
To reach the goal, we add a new plugin inside the plugins section of the module application
’s pom.xml file
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/static/</outputDirectory>
<resources>
<resource>
<directory>${project.parent.basedir}/gui-test/build</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Conclusion
This is a solution that will be very useful when the project needs a GUI to interact with the module that can be quickly set up. This solution provides a unique deploy in the first phase of the deployment although the build phase requires downloading and installing Node and all the dependencies, heavily affecting the total build time of the application In case the GUI will evolve, the best solution is to divide the modules so that the overall infrastructure is ready to scale up. The journey to become a more hybrid developer has begun, I hope I will continue to write articles about merging the worlds of BackEnd and FrontEnd