My solution to the question I posted on Reddit.
A even more optimal way is to use Spring BOM instead of Spring Parent in the backend POM.
With BOM, you can properly set the parent of the backend project to the root level POM.
However I can't figure out how to set Spring BOM properly, so you have to do it yourself.
-
Create an empty top-level pom:
mvn archetype:generate "-DarchetypeGroupId=org.codehaus.mojo.archetypes" "-DarchetypeArtifactId=pom-root" "-DarchetypeVersion=RELEASE"
-
Create an child maven module (for the React project):
mvn archetype:generate "-DarchetypeGroupId=org.apache.maven.archetypes" "-DarchetypeArtifactId=maven-archetype-quickstart" "-DarchetypeVersion=RELEASE"
-
Copy the content of
pom.xmlin the newly generated folder and paste it to a temp notepad, then delete the folder -
Create a new React project (I used Vite with NPM):
npm create vite@latest
-
Create a
pom.xmlinside the newly generated folder and paste the content you copied in step 3 into it. -
Replace the whole
<properties>section with the following:
<properties>
<!-- Change as appropiate -->
<node.version>v20.9.0</node.version>
<frontend-maven-plugin.version>1.14.2</frontend-maven-plugin.version>
<frontend.build.output.dir>${basedir}/dist</frontend.build.output.dir>
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
</properties>- Create a Spring Boot project with Spring Initializr with the dependencies you need. You should at least add
Spring Web - Download and unzip the Spring Boot project onto the top-level folder
- Add
<module>backend</module>item into the<modules>section in the top-levelpom.xml(Replacebackendwith the folder name of your Spring Boot folder) - Move the maven related item in the
backendfolder to top-level:
-
mv mvnw* .. -
mv .mvn ..
Now your folder structure should be something like this:
root
|
|- backend
| |- pom.xml
| |- src
| |- Java source files...
| |_ Other files...
|
|- frontend
| |- pom.xml
| |- src
| |- React source files...
| |_ Other folder and files...
|
|- pom.xml
|
|_ Other Maven related items...
- Open the
pom.xmlin thefrontendfolder with an editor.
Replace the whole <pluginManagement> section with the following:
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<phase>generate-resources</phase>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<phase>generate-resources</phase>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<phase>generate-resources</phase>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<executions>
<execution>
<id>copy react build files</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
<resources>
<resource>
<directory>${frontend.build.output.dir}</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>- Add the
frontendmodule as dependency into thebackendmodule (add tobackend/pom.xml):
<!-- Change as appropiate -->
<dependency>
<groupId>com.example</groupId>
<artifactId>frontend</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>-
Run
mvn clean verifyin the top-level folder. Then find the Spring Boot JAR inbackend/target -
Run the JAR:
java -jar <jar-filename>. Go tolocalhost:8080and you should see the React page!
Stack Overflow: How to integrate a React webapp inside a spring boot Application with jar packaging
