在同一端口上运行 React 前端和 SpringBoot 后端,并将它们打包成一个单独的工件!
这种设置的优点
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
了解如何将create-react-app与 Spring Boot 结合使用,从而生成单个工件。
大家好!我是一名拥有三年以上经验的全栈开发人员,目前居住在印度西孟加拉邦。今天,我将向大家介绍一个设置技巧,帮助您准备项目结构,以便在同一个端口上运行 React 和 Spring Boot 应用,并将它们打包成一个单独的文件。您将会看到,在使用这两种颠覆性技术时,这种方法能如何简化开发流程。
这是我接下来要讲解的演示程序的GitHub链接。
这种设置的优点
-
结合了create-react-app和 Spring Boot的易用性。
-
在开发前端时,您可以使用create-react-app的热重载功能,在进行更改后保存页面,更改将立即反映在浏览器中。
-
使用 Spring Boot,您可以轻松管理开发版本(使用 SNAPSHOT)和生产环境中的发布版本。您可以使用Spring Actuator或 Spring Admin 在运行时检测 Spring Boot 的构建版本和时间,它们不仅提供构建元数据功能,还提供更多其他功能。
-
将前端和后端打包到一个 war/jar 文件中,并进行优化的生产构建。
我在最近的一个项目中学到了这一点。该项目包含多个基于 Spring Boot 的微服务,前端采用 React,它们被打包并部署为独立的单个组件。
所以,这里提供一个快速指南,介绍如何在同一端口上运行 React 前端和 Spring Boot 后端,以及如何将它们打包成一个单独的 jar 文件。
首先,使用https://start.spring.io创建一个 Spring Boot 项目。添加 Web 依赖项。将 groupId 和 artifactId 设置为你想要的任何值。生成项目并将其解压缩到你的项目目录中。
或者,如果您使用的是 Spring Tools Suite,您可以直接点击File->New->Spring Starter Project并填写所需详细信息来创建一个 Spring Boot 项目。
您的初始 pom.xml 文件应该如下所示。
项目结构应如下所示。
您现在可以运行该应用程序,看看它是否运行正常,没有任何错误。不过,如果您访问http://localhost:8080/,
将不会看到任何内容。
现在,前往[此处插入路径] src/main/resources,创建一个static文件夹。在该文件夹内创建一个test.html文件,并在其中写入一些文本。
现在,如果您重启应用程序并访问http://localhost:8080/test.html,您会看到它在8080 端口启动您的 html 页面。您可以在浏览器中看到文件的内容。
在 8080 端口上通过 Spring Boot 提供 React 应用服务,并将它们打包在一起。
我们将利用 Spring Boot 的上述特性来提供 React 项目的单页服务。static我们将从项目目录下的文件夹中提供 HTML 页面target,而不是从源代码目录中提供。
现在让我们使用create-react-appsrc/main创建一个 React 应用。在终端中导航到你的文件夹D:\Codes_projects\springboot_react_maven_plugin\Spring_React_maven-plugin\src\main>并运行npx create-react-app frontend。
这应该会在其中创建一个 React 应用src/main。现在,如果你查看你的文件夹结构,它应该看起来像这样。
cd frontend你可以通过执行以下命令yarn start来运行 React 应用:`react app --run`和 `react app --run`。它应该会在http://localhost:3000npm start上启动 React 应用。
您可以通过运行以下命令创建前端的生产版本yarn build。运行构建命令后,您的文件夹结构将如下所示。
您需要将此生产版本复制到target/classes您的项目目录中,以便 Spring Bootindex.html在您启动项目时能够提供此版本。
所以,有两个步骤——
- 创建前端的生产版本
- 将生产环境构建复制到 ${target/classes/}
当然,你不可能手动完成这项工作。
我们会用两个工具maven plugins来完成。
- 第一步的前端 Maven 插件。
- 步骤 2 的maven-resources-plugin 。
pom.xml在您的“部分”下添加以下内容,并按所示plugins进行更新。properties section
<properties>
<java.version>1.8</java.version>
<frontend-src-dir>${project.basedir}/src/main/frontend</frontend-src-dir>
<node.version>v14.15.4</node.version>
<yarn.version>v1.16.0</yarn.version>
<frontend-maven-plugin.version>1.7.6</frontend-maven-plugin.version>
</properties>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<yarnVersion>${yarn.version}</yarnVersion>
<workingDirectory>${frontend-src-dir}</workingDirectory>
<installDirectory>${project.build.directory}</installDirectory>
</configuration>
<executions>
<execution>
<id>install-frontend-tools</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
</execution>
<execution>
<id>yarn-install</id>
<goals>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>build-frontend</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<arguments>build</arguments>
</configuration>
</execution>
</executions>
</plugin>
现在,如果您mvn clean install从Maven 运行,它将在本地安装 npm、yarn 和 node,并在前端目录中运行 npm build。
D:\Codes_projects\springboot_react_maven_plugin\Spring_React_maven-plugin>
文件夹结构如下所示:
现在,将第二个插件添加到你的pom.xml.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>position-react-build</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
<resources>
<resource>
<directory>${frontend-src-dir}/build</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
在依赖项部分添加以下依赖项。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
修改文件spring-boot-maven-plugin,使其包含配置部分。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
这将确保前端构建文件在生成后被复制yarn build。
现在,mvn clean install再次运行并target/classes/static从文件管理器中检查目录。
里面会包含前端生产环境的构建文件。
你的最终作品pom.xml将如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.springreact</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Run React Frontend and SpringBoot Backend on the same port.</description>
<properties>
<java.version>1.8</java.version>
<frontend-src-dir>${project.basedir}/src/main/frontend</frontend-src-dir>
<node.version>v14.15.4</node.version>
<yarn.version>v1.16.0</yarn.version>
<frontend-maven-plugin.version>1.7.6</frontend-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<yarnVersion>${yarn.version}</yarnVersion>
<workingDirectory>${frontend-src-dir}</workingDirectory>
<installDirectory>${project.build.directory}</installDirectory>
</configuration>
<executions>
<execution>
<id>install-frontend-tools</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
</execution>
<execution>
<id>yarn-install</id>
<goals>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>build-frontend</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<arguments>build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>position-react-build</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
<resources>
<resource>
<directory>${frontend-src-dir}/build</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
现在一切就绪!运行项目并访问http://localhost:8080/index.html瞧!你已经通过 Spring Boot 运行了你的 React 应用。
更进一步
您可以添加rest controllers并公开一个端点作为应用程序的启动点。例如,每当应用程序加载时,Spring Boot 都会从前端项目的优化构建中Index Controller启动包含静态内容的文件。这样,您只需访问http://localhost:8080即可,而无需硬编码文件名。index.htmltarget directoryindex.html
我们来做这件事。
在以下文件夹结构中添加一个控制器。
package com.springreact.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class IndexController {
@GetMapping("")
public ModelAndView home() {
ModelAndView mav=new ModelAndView("index");
return mav;
}
}
运行你的应用程序,然后访问http://localhost:8080/。
你看到什么了吗?没有,对吧!
要使此功能正常工作,还需要添加另一个依赖项。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
现在,默认情况下,它thymleaf会在 . 中查找我们的模板src/main/resources/templates。我们可以将模板放在那里,并将它们组织在子目录中,这样就不会有问题了。
那么,我们来试试。在文件夹内添加一个src/main/resources/templates名为`html` 的 HTML 文件index.html,并在其中添加一些内容。
运行应用程序并访问http://localhost:8080。您将看到index.html服务src/main/resources/templates在8080 端口上运行。
现在,要更改此默认行为并thymleaf从其他位置提供静态内容,您需要向application.properties文件中添加一个条目。
spring.thymeleaf.prefix=file:///D:///Codes_projects//springboot_react_maven_plugin//Spring_React_maven-plugin//target//classes//static/
这里,我把路径硬编码进去了。
最后,现在如果你创建并启动你的项目,你可以看到 React 应用直接在8080 端口update上运行。
结论
您已经学会了如何使用 Spring Boot 运行 React 应用。您可以将前端和后端运行在同一个端口上。我已经解释了完成设置所需的步骤。现在您可以创建一个实际的应用,并体验使用此设置进行开发的便捷高效。您现在可以通过运行 `react-scripts` 来运行前端应用cd frontend;并使用create-react-appyarn start的热重载功能进行开发,同时还能获得清晰易懂的错误信息,并将应用作为一个单独的组件部署到测试和生产环境。
感谢阅读!
如果您觉得这篇文章有用,请留言。欢迎提出任何反馈或建议。
文章来源:https://dev.to/arpan_banerjee7/run-react-frontend-and-springboot-backend-on-the-same-port-and-package-them-as-a-single-artifact-14pa














