使用 React 与 Vert.x 构建单页应用 (SPA)
本指南将向你展示如何协同开发一个以前端 React 单页应用为界面、以 Vert.x 为高性能后端的现代 Web 架构体系。
你将构建什么
你将构建一个 React 前端应用,通过 HTTP 与后端的 Vert.x REST 服务进行通信。
开发期工作流 (Development Workflow)
在开发单页应用(SPA)时,对 JavaScript、HTML 或 CSS 文件的每次修改都能即时获得热重载(Fast Refresh)反馈至关重要。
在 React 生态中,这通常需要使用 npm 启动一个前端本地开发服务器来分发静态资源:
那么,前端发起的业务 API 请求该如何无缝交由 Vert.x 后端处理呢?
我们将配置前端工程的代理机制,让前端开发服务器自动将 /api 请求反向代理给 Vert.x:
创建工程项目
本项目代码同时支持 Maven 与 Gradle。
使用 Maven
在 Maven pom.xml 中引入 vertx-web 依赖:
pom.xml <dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>${vertx.version}</version>
</dependency>
</dependencies>
随后配置 exec-maven-plugin 插件以便于直接在终端启动:
pom.xml <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<mainClass>io.vertx.howtos.react.BackendVerticle</mainClass>
</configuration>
</plugin>
使用 Gradle
使用 Gradle Kotlin DSL 时,添加 vertx-web 依赖:
build.gradle.ktsdependencies {
val vertxVersion = "5.0.0.CR2"
implementation("io.vertx:vertx-web:${vertxVersion}")
}
并配置应用程序的主类入口:
build.gradle.ktsapplication {
mainClass = "io.vertx.howtos.react.BackendVerticle"
}
通过 HTTP 暴露后端问候服务
首先编写后端服务。它将在 /api/message 路径上监听请求并返回一条问候消息:
src/main/java/io/vertx/howtos/react/BackendVerticle.java Router router = Router.router(vertx);
Route messageRoute = router.get("/api/message"); (1)
messageRoute.handler(rc -> {
rc.response().end("Hello React from Vert.x!"); (2)
});
router.get().handler(StaticHandler.create()); (3)
return vertx.createHttpServer()
.requestHandler(router)
.listen(8080);
| 1 | 定义一条匹配 /api/message 路径的 Vert.x Web 路由; |
| 2 | 路由处理器向客户端响应一条欢迎文本; |
| 3 | 挂载 StaticHandler,用于向浏览器分发前端生产编译后的静态文件。 |
你可能会好奇:既然开发期前端开发服务器已经分发了静态文件,为什么后端还要挂载 StaticHandler?请记住,在生产环境中,前端会被整体打包并嵌入后端 JAR 中,由 Vert.x HTTP 服务器全权托管。
|
在测试之前,为 BackendVerticle 添加 main 方法:
src/main/java/io/vertx/howtos/react/BackendVerticle.java public static void main(String[] args) {
Vertx vertx = Vertx.vertx(); (1)
vertx.deployVerticle(new BackendVerticle()).await(); (2)
System.out.println("Verticle started!");
}
| 1 | 创建 Vertx 核心上下文; |
| 2 | 部署 BackendVerticle。 |
你可以通过以下命令启动后端服务:
-
直接在 IDE 中运行;
-
使用 Maven:
mvn compile exec:java; -
使用 Gradle:
./gradlew run。
服务启动后,使用 curl 或 httpie 进行测试:
http :8080/api/message
你将看到返回:
HTTP/1.1 200 OK
content-length: 24
Hello React from Vert.x!
在浏览器中显示响应消息
后端服务运行正常后,我们开始创建 React 前端应用。
在 src/main 目录下使用 npx 运行 create-react-app:
cd src/main
npx create-react-app frontend
这会自动生成基础的项目骨架与依赖配置。 清空默认样板代码:
rm -rf frontend/src/*
随后编写 React 核心业务组件:
src/main/frontend/src/index.jsimport React from 'react';
import ReactDOM from 'react-dom';
class Greeter extends React.Component { (1)
constructor(props) {
super(props);
this.state = { (2)
message: "Default message"
}
}
componentDidMount() { (5)
fetch("/api/message")
.then(response => response.text())
.then(text => this.setState({message: text}));
}
render() { (3)
return (
<div>
<span>{this.state.message}</span>
</div>
);
}
}
ReactDOM.render( (4)
<Greeter/>,
document.getElementById('root')
);
| 1 | 前端包含一个单一的 React Greeter 组件; |
| 2 | Greeter 维护组件内部状态(用于在页面中展示的文本信息); |
| 3 | 状态内容渲染在简单的 HTML span 标签中; |
| 4 | 将组件挂载到 DOM 树中; |
| 5 | 组件完成初次挂载渲染后,通过 fetch 向后端 API 发起 HTTP 请求,并将返回的数据更新至组件状态中。 |
至关重要的一步:配置开发服务器代理。在 src/main/frontend/package.json 中添加:
src/main/frontend/package.json"proxy": "http://localhost:8080"
现在,启动前端开发服务器:
cd src/main/frontend
npm start
浏览器将自动打开 http://localhost:3000,页面上将即时显示:
Hello React from Vert.x!
生产环境打包集成
在生产环境中,我们不会运行独立的前端开发服务器。Maven 或 Gradle 会被配置为:
-
自动执行前端构建打包;
-
将生成的静态资源复制到
src/main/resources/webroot目录下。
在 Maven pom.xml 中引入前端构建插件:
pom.xml <plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.7.6</version>
<configuration>
<nodeVersion>v22.12.0</nodeVersion>
<npmVersion>10.9.0</npmVersion>
<workingDirectory>src/main/frontend</workingDirectory>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install-node-and-npm</id>
<phase>generate-resources</phase>
<goals>
<goal>install-node-and-npm</goal> (1)
</goals>
</execution>
<execution>
<phase>generate-resources</phase>
<id>npm-install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments> (2)
</configuration>
</execution>
<execution>
<id>npm-run-build</id>
<phase>generate-resources</phase>
<goals>
<goal>npm</goal> (3)
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-to-webroot</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal> (4)
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/webroot</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/frontend/build</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
| 1 | 在构建目录中自动下载独立的 Node.js 与 npm,确保在无 Node 环境的 CI 流水线上也能稳定构建; |
| 2 | 执行 npm install 下载前端依赖; |
| 3 | 运行 npm run build 生成高度压缩的生产制品; |
| 4 | 将生产制品自动复制到 src/main/resources/webroot。 |
完成打包后,直接启动 Vert.x 服务器并在浏览器访问 http://localhost:8080,即可看到完整打包一体化的 SPA 单页应用。
本文总结
本指南涵盖了:
-
使用
create-react-app快速搭建 React 前端; -
利用开发期代理机制实现前端热重载与后端 API 联调解耦;
-
在生产构建流程中将前端静态产物与 Vert.x 后端合并打包分发。