如何使用 jar 打包将 React webapp 集成到 spring 引导应用程序中
How to integrate a React webapp inside a spring boot Application with jar packaging
我们有一个 React webapp 和一个 spring 启动应用程序(用 maven 构建)正在开发中。
React 应用程序(在 npm 上)和启动应用程序分别 运行ning,但现在是时候将它们集成并放入 QA/staging.
我们正在使用 webpack 来捆绑 React 应用程序。
引导应用程序是一个带有 REST API(由反应前端使用)和休眠以实现数据库持久性的单个模块。
问题
- react 和 boot app 的目录结构应该是什么?我们想将整个应用程序(前端和后端)部署为 .jar(spring boot uberjar)
- React 应用程序开发工作流程是什么?无需 运行 maven 和 运行 java -jar 的工作流]
我在网络上找到了一些资源,其中反应和启动应用程序都在单独的 repos/directories 上,没有任何集成,这不是最佳选择;我还没有找到一个资源,其中 webapp 资源和启动资源都在同一目录树中,这也说明了开发生命周期和生产生命周期。
奖金:反应开发人员只知道 html/js/css。他们的 vscode/webstorm 项目中是否可能只有 React 应用程序资源?
我建议创建多模块 Maven 项目,其中一个模块是 spring-boot 应用程序,第二个模块是 React 应用程序。要将其放入 uber jar,请将 React 应用程序打包到 Maven 构建的 webjar 中。
构建也可以通过 maven 使用适当的插件来完成。
所以:
- 在项目的子目录中创建普通的 React 应用程序(通过 npm 等构建)
- 添加到此应用程序 pom.xml 这将 compile javascript on maven compile and pack it into proper webjar structure
- 在 spring-boot 模块中添加 react 一个作为正常的 maven 依赖项。 Check out this tutorial
这将允许您将所有内容都作为一个 uber jar 应用程序。另一方面,front-end 人们可以像使用任何其他 React 应用程序一样使用 React 模块。
我发现这个 post 可以回答您的问题。它展示了如何开发反应前端和 spring 引导后端,然后将它们合并到一个 jar 文件中进行部署。
https://medium.com/@mukundmadhav/build-and-deploy-react-app-with-spring-boot-and-mysql-6f888eb0c600
您可以 运行 React 和 Spring 在同一个端口上启动并将它们打包为一个工件!!
请按照我在此处解释的步骤进行操作,这些步骤应该会让您 运行ning。
回答你的问题-
- 目录结构如下图所示。两者都在同一个根目录下。
- 关于 React 应用程序开发工作流程 - 您可以按照开发前端 React 项目的方式进行开发,使用热重载(保存文件,更改将自动反映)和有意义的错误消息.您将不得不使用代理进行通信。
Here is the Github link of the demo project that I am going to
explain here
Spring 启动可以提供来自 src/main/resources/static
文件夹的静态内容。我们将利用 Spring Boot 的上述功能来为 React 项目的单页服务。我们将从目标目录中的静态文件夹提供一个 html 页面,而不是在源目录中。
项目结构-
首先,用 https://start.spring.io 创建一个 spring 引导项目。添加 Web 依赖项。将 groupId 和 artifactId 设置为您想要的任何值。生成项目并将其解压缩到您的项目目录中。
或者,如果您使用的是 Spring 工具套件,您只需单击
File->New->Spring Starter Project
并提及创建 spring 引导项目所需的详细信息。
src/main
中的 frontend
文件夹应该使用 create-react-app.
构建你的 React 应用程序
所以,有两步-
- 创建前端的生产版本。
- 将生产版本复制到 ${target/classes/}。
我们将使用两个 Maven 插件和 Thymleaf。
- frontend-maven-plugin 第 1 步。
- maven-resources-plugin 用于第 2 步。
对于第 1 步中的 frontend-maven-plugin-- 如果您仔细查看 pom.xml
那里我提到了 src
directroy 从哪里frontend-maven-plugin 将获取文件,创建生产版本并将内容放入提到的输出目录中(在 src/main/frontend/build
中)。
<workingDirectory>${frontend-src-dir}</workingDirectory>
<installDirectory>${project.build.directory}</installDirectory>
对于第 2 步中的 maven-resources-plugin-- 它将采用刚刚由 frontend-maven-plugin 创建的生产版本并将其放置在您的根目录中target/classes/static
.
然后我们将使用 Thymleaf 通过控制器中的休息端点提供来自 target/classes/static
的静态内容。否则您必须输入 html file
的名称,例如 http://localhost:8080/index.html
你的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>
这是控制器代码。
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;
}
}
如果您按照上述步骤操作,您应该会看到您的 React 应用程序在 http://localhost:8080/
上启动。
有关详细信息,您可以查看我在上面写的博客。下面是博客在两个不同平台的链接-
回答关于创建超级 jar 还是将应用程序打包在单个 jar 中是最佳做法的问题。这取决于某些事情。就像前任一样。如果您在您的应用程序中实现了 oauth2 并且想要访问其余端点而无需实现访问令牌等逻辑。你可以把它放在一个罐子里。否则您必须使用 header.
中的访问令牌创建一个 header
我们有一个 React webapp 和一个 spring 启动应用程序(用 maven 构建)正在开发中。
React 应用程序(在 npm 上)和启动应用程序分别 运行ning,但现在是时候将它们集成并放入 QA/staging.
我们正在使用 webpack 来捆绑 React 应用程序。
引导应用程序是一个带有 REST API(由反应前端使用)和休眠以实现数据库持久性的单个模块。
问题
- react 和 boot app 的目录结构应该是什么?我们想将整个应用程序(前端和后端)部署为 .jar(spring boot uberjar)
- React 应用程序开发工作流程是什么?无需 运行 maven 和 运行 java -jar 的工作流]
我在网络上找到了一些资源,其中反应和启动应用程序都在单独的 repos/directories 上,没有任何集成,这不是最佳选择;我还没有找到一个资源,其中 webapp 资源和启动资源都在同一目录树中,这也说明了开发生命周期和生产生命周期。
奖金:反应开发人员只知道 html/js/css。他们的 vscode/webstorm 项目中是否可能只有 React 应用程序资源?
我建议创建多模块 Maven 项目,其中一个模块是 spring-boot 应用程序,第二个模块是 React 应用程序。要将其放入 uber jar,请将 React 应用程序打包到 Maven 构建的 webjar 中。 构建也可以通过 maven 使用适当的插件来完成。
所以:
- 在项目的子目录中创建普通的 React 应用程序(通过 npm 等构建)
- 添加到此应用程序 pom.xml 这将 compile javascript on maven compile and pack it into proper webjar structure
- 在 spring-boot 模块中添加 react 一个作为正常的 maven 依赖项。 Check out this tutorial
这将允许您将所有内容都作为一个 uber jar 应用程序。另一方面,front-end 人们可以像使用任何其他 React 应用程序一样使用 React 模块。
我发现这个 post 可以回答您的问题。它展示了如何开发反应前端和 spring 引导后端,然后将它们合并到一个 jar 文件中进行部署。
https://medium.com/@mukundmadhav/build-and-deploy-react-app-with-spring-boot-and-mysql-6f888eb0c600
您可以 运行 React 和 Spring 在同一个端口上启动并将它们打包为一个工件!! 请按照我在此处解释的步骤进行操作,这些步骤应该会让您 运行ning。 回答你的问题-
- 目录结构如下图所示。两者都在同一个根目录下。
- 关于 React 应用程序开发工作流程 - 您可以按照开发前端 React 项目的方式进行开发,使用热重载(保存文件,更改将自动反映)和有意义的错误消息.您将不得不使用代理进行通信。
Here is the Github link of the demo project that I am going to explain here
Spring 启动可以提供来自 src/main/resources/static
文件夹的静态内容。我们将利用 Spring Boot 的上述功能来为 React 项目的单页服务。我们将从目标目录中的静态文件夹提供一个 html 页面,而不是在源目录中。
项目结构-
首先,用 https://start.spring.io 创建一个 spring 引导项目。添加 Web 依赖项。将 groupId 和 artifactId 设置为您想要的任何值。生成项目并将其解压缩到您的项目目录中。
或者,如果您使用的是 Spring 工具套件,您只需单击
File->New->Spring Starter Project
并提及创建 spring 引导项目所需的详细信息。
src/main
中的 frontend
文件夹应该使用 create-react-app.
所以,有两步-
- 创建前端的生产版本。
- 将生产版本复制到 ${target/classes/}。
我们将使用两个 Maven 插件和 Thymleaf。
- frontend-maven-plugin 第 1 步。
- maven-resources-plugin 用于第 2 步。
对于第 1 步中的 frontend-maven-plugin-- 如果您仔细查看 pom.xml
那里我提到了 src
directroy 从哪里frontend-maven-plugin 将获取文件,创建生产版本并将内容放入提到的输出目录中(在 src/main/frontend/build
中)。
<workingDirectory>${frontend-src-dir}</workingDirectory>
<installDirectory>${project.build.directory}</installDirectory>
对于第 2 步中的 maven-resources-plugin-- 它将采用刚刚由 frontend-maven-plugin 创建的生产版本并将其放置在您的根目录中target/classes/static
.
然后我们将使用 Thymleaf 通过控制器中的休息端点提供来自 target/classes/static
的静态内容。否则您必须输入 html file
的名称,例如 http://localhost:8080/index.html
你的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>
这是控制器代码。
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;
}
}
如果您按照上述步骤操作,您应该会看到您的 React 应用程序在 http://localhost:8080/
上启动。
有关详细信息,您可以查看我在上面写的博客。下面是博客在两个不同平台的链接-
回答关于创建超级 jar 还是将应用程序打包在单个 jar 中是最佳做法的问题。这取决于某些事情。就像前任一样。如果您在您的应用程序中实现了 oauth2 并且想要访问其余端点而无需实现访问令牌等逻辑。你可以把它放在一个罐子里。否则您必须使用 header.
中的访问令牌创建一个 header