Skip to content

Latest commit

 

History

History
170 lines (135 loc) · 5 KB

File metadata and controls

170 lines (135 loc) · 5 KB

Spring Boot & React, Maven Multi-Modules Example

My solution to the question I posted on Reddit.

Note

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.

Instruction

First steps

  1. Create an empty top-level pom:

    • mvn archetype:generate "-DarchetypeGroupId=org.codehaus.mojo.archetypes" "-DarchetypeArtifactId=pom-root" "-DarchetypeVersion=RELEASE"
  2. Create an child maven module (for the React project):

    • mvn archetype:generate "-DarchetypeGroupId=org.apache.maven.archetypes" "-DarchetypeArtifactId=maven-archetype-quickstart" "-DarchetypeVersion=RELEASE"
  3. Copy the content of pom.xml in the newly generated folder and paste it to a temp notepad, then delete the folder

  4. Create a new React project (I used Vite with NPM):

    • npm create vite@latest
  5. Create a pom.xml inside the newly generated folder and paste the content you copied in step 3 into it.

  6. 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>
  1. Create a Spring Boot project with Spring Initializr with the dependencies you need. You should at least add Spring Web
  2. Download and unzip the Spring Boot project onto the top-level folder
  3. Add <module>backend</module> item into the <modules> section in the top-level pom.xml (Replace backend with the folder name of your Spring Boot folder)
  4. Move the maven related item in the backend folder 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...

Preparing build

  1. Open the pom.xml in the frontend folder 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>
  1. Add the frontend module as dependency into the backend module (add to backend/pom.xml):
<!-- Change as appropiate -->
<dependency>
  <groupId>com.example</groupId>
  <artifactId>frontend</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>
  1. Run mvn clean verify in the top-level folder. Then find the Spring Boot JAR in backend/target

  2. Run the JAR: java -jar <jar-filename>. Go to localhost:8080 and you should see the React page!

Success

Reference

Stack Overflow: How to integrate a React webapp inside a spring boot Application with jar packaging

Spring: Creating a Multi Module Project