JAiRouter单仓一体架构深解:前后端分离开发与Maven一体化构建的最佳实践
JAiRouter单仓一体架构解析:前后端一体化构建实践 本文介绍了JAiRouter项目采用的前后端分离但代码仓库合并的架构方案,通过frontend-maven-plugin实现Node/NPM与Maven工具链的无缝整合。文章详细阐述了该架构的目录布局、核心构建流程、开发期代理配置等关键技术点,并提供了构建性能优化、多架构镜像生成等实用技巧。实践表明,该方案使首次构建时间从5分20秒降至2分
JAiRouter单仓一体架构深解:前后端分离开发与Maven一体化构建的最佳实践
文章目录
1. 背景与目标
云原生时代,交付物逐渐向容器镜像收敛,研发流程要求"一键出包、快速迭代、可重复构建"。JaiRouter 项目采用 前后端分离架构(Vue3 + Vite 作为 Console,Spring Boot 作为 API 网关),但源码仓库保持 mono-repo 形态以降低认知负荷与 CI/CD 复杂度。
本文旨在阐述如何利用 frontend-maven-plugin 将两套异构工具链(Node/NPM 与 Maven)串联成 single-command build,并兼顾:
- 开发期 热更新代理
- 构建期 缓存最大化
- 发布期 多架构 OCI 镜像
2. 整体架构与目录布局
关键路径说明
- frontend:Vue3 + TypeScript + Element Plus + Vite
- backend:Spring Boot 3 + Java 17(主 pom 所在)
- static/admin:Servlet 容器静态资源映射前缀,对应 Vite
base: '/admin/'
3. 核心构建流程拆解
Phase | Plugin / Goal | Output | Cache Key |
---|---|---|---|
generate-resources |
install-node-and-npm |
target/node/ |
node-version + os.detected.classifier |
generate-resources |
npm (install) |
frontend/node_modules/ |
package-lock.json hash |
generate-resources |
npm (run build) |
frontend/dist/ |
src/**/* hash |
process-resources |
copy-resources |
static/admin/ |
- |
package |
spring-boot:build-image |
OCI image tarball | layer digest |
通过
mode=max
与 GitHub Actionsactions/cache@v3
实现 跨工作流 中间层复用,平均节省 65% 构建耗时。
4. 深度技巧揭秘
4.1 开发期零跨域
// vite.config.ts
server: {
proxy: {
'/api': { target: 'http://localhost:8080', changeOrigin: true },
'/ws': { target: 'ws://localhost:8080', ws: true }
}
}
浏览器仍访问 http://localhost:3000/admin
,但 XHR/WebSocket 被 Vite dev-server 反向代理至后端,无 CORS 且保持 Cookie 同源。
4.2 构建期版本对齐
<execution>
<id>npm-run-build</id>
<phase>generate-resources</phase>
</execution>
Maven 生命周期保证:任何早于 process-resources
的测试或代码生成任务均能拿到最新静态文件,确保可重复构建(reproducible build)。
4.3 跳过开关(backward compatibility)
mvn clean package -Dskip.frontend.build=true
对于仅修改 Java 代码的场景,可完全跳过前端阶段,平均再节省 30-40 s。
4.4 多架构 OCI 镜像
- uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
层缓存与 QEMU 仿真结合,同一次 push 即可产出双架构镜像,无需自建 ARM 节点。
5. 常见问题 FAQ
现象 | 根本原因 | 解决方案 |
---|---|---|
执行 mvn 报错 “npm: not found” |
插件尚未完成 Node 自举 | 保证宿主机可访问外网,重跑一次即可触发下载 |
访问 /admin 出现 404 |
frontend/dist 未被拷入 jar |
检查 maven-resources-plugin 的 <directory> 是否指向 frontend/dist |
arm64 构建耗时 >10 min | 纯 QEMU 软件模拟效率低 | 引入云端 ARM 实例或自托管 ARM Runner |
前端热更新失灵(WSL) | bind-mount 性能差 | 升级至 WSL2,或在 Linux 原生环境开发 |
SNAPSHOT 包体积异常增大 | 历史 dist 未清理 |
执行 mvn clean 或在 vite.config.ts 开启 emptyOutDir: true |
想单独升级 Node 版本 | 仅需修改 nodeVersion 标签 |
删除 target/node 目录触发重新下载 |
6. Benchmark & 效果
Metric | Before* | After |
---|---|---|
首次克隆构建耗时 | 5 min 20 s | 2 min 45 s |
仅后端改动耗时 | 1 min 10 s | 35 s |
镜像体积 | 184 MB | 142 MB(dist 压缩+layer dedup) |
跨架构构建 | 手动分两次 | 单任务 6 min(含缓存) |
*Before:独立前端仓库 + 手动 scp dist
+ 单架构 buildx
7. 一键模板
<!-- 多模块前端构建插件配置 -->
<!-- Frontend Maven Plugin -->
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.15.0</version>
<configuration>
<workingDirectory>frontend/</workingDirectory>
<installDirectory>target</installDirectory>
<!-- 添加跳过配置 -->
<skip>${skip.frontend.build}</skip>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v18.17.0</nodeVersion>
<npmVersion>9.6.7</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<!-- Copy frontend build to static resources -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-frontend-build</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/static/admin</outputDirectory>
<resources>
<resource>
<directory>frontend/dist</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
mvn clean package
直出可运行 jar- 自带
/admin
管理后台 - CI 层缓存加速 & 多架构镜像
8. 结语
通过 frontend-maven-plugin 将 Node 生态嵌入 Maven 生命周期,我们兼顾了前后端分离的开发敏捷性与mono-repo 的构建一致性,实现了真正的 “code together, ship together”。
该范式已应用于 JaiRouter 主干分支。
更多推荐
所有评论(0)