如何搭建按功能模块拆分的Java后端+Reactjs前端项目并配置Maven/Gradle构建
多模块React+Java项目构建配置方案
整体思路分为Java侧多模块聚合、前端侧跨模块代码收集构建两部分,以下分别给出Maven和Gradle的配置方法:
前置准备
先在根目录新增一个boot模块作为SpringBoot启动入口,无业务代码,仅负责聚合所有依赖并打包,最终运行的jar包由该模块产出。
Maven配置方案
1. 根POM聚合配置
根目录的pom.xml设置打包类型为pom,声明所有子模块:
<packaging>pom</packaging> <modules> <module>auth0</module> <module>security</module> <module>core</module> <module>feature1</module> <!-- 替换为实际功能模块名 --> <module>feature2</module> <module>boot</module> </modules>
2. 依赖关系配置
- auth0、security为基础公共依赖,无其他模块依赖
- core模块依赖auth0、security,存放Java公共工具类和React基础代码
- 所有feature功能模块依赖core模块
- boot模块依赖所有feature功能模块,保证打包时能聚合所有Java代码
3. 前端构建配置
在boot模块的pom.xml中配置插件完成前端代码收集、构建、资源复制:
第一步:用maven-antrun-plugin收集所有模块的ui代码
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>generate-resources</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <!-- 清空临时前端工作目录 --> <delete dir="./frontend-temp"/> <mkdir dir="./frontend-temp/src"/> <!-- 复制core模块的前端配置和基础代码 --> <copy todir="./frontend-temp"> <fileset dir="../core/src/main/ui" includes="package.json, vite.config.js, index.html, public/**"/> </copy> <copy todir="./frontend-temp/src"> <fileset dir="../core/src/main/ui/src"/> </copy> <!-- 复制所有feature模块的ui代码,按模块名存放到子目录避免冲突 --> <copy todir="./frontend-temp/src/feature1"> <fileset dir="../feature1/src/main/ui/src"/> </copy> <copy todir="./frontend-temp/src/feature2"> <fileset dir="../feature2/src/main/ui/src"/> </copy> </tasks> </configuration> </execution> </executions> </plugin>
第二步:用frontend-maven-plugin执行前端构建
<plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.14.2</version> <configuration> <workingDirectory>./frontend-temp</workingDirectory> <installDirectory>./node-env</installDirectory> </configuration> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <configuration> <nodeVersion>v20.10.0</nodeVersion> <!-- 替换为你使用的node版本 --> </configuration> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>install</arguments> </configuration> </execution> <execution> <id>npm build</id> <goals> <goal>npm</goal> </goals> <configuration> <!-- 构建产物直接输出到SpringBoot静态资源目录 --> <arguments>run build -- --outDir ../src/main/resources/static</arguments> </configuration> </execution> </executions> </plugin>
4. Java侧扫描配置
boot模块的SpringBoot启动类加上全局包扫描注解,保证所有模块的Bean都能被加载:
@SpringBootApplication @ComponentScan(basePackages = "替换为你的根包名,比如com.xxx.xxx") public class BootApplication { public static void main(String[] args) { SpringApplication.run(BootApplication.class, args); } }
Gradle配置方案
整体逻辑和Maven完全一致,仅语法不同:
1. 根项目聚合配置
根目录的settings.gradle声明所有子模块:
rootProject.name = '你的项目名' include 'auth0', 'security', 'core', 'feature1', 'feature2', 'boot'
2. 依赖关系配置
在根build.gradle中统一声明依赖关系,或者各子模块自行声明依赖,规则和Maven相同:core依赖auth0、security,feature依赖core,boot依赖所有feature。
3. 前端构建配置
在boot模块的build.gradle中引入node插件,配置收集和构建任务:
plugins { id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' id 'java' id "com.github.node-gradle.node" version "5.0.0" } // 配置node插件 node { version = "20.10.0" download = true workDir = file("${projectDir}/node-env") nodeModulesDir = file("${projectDir}/frontend-temp") } // 收集所有模块ui代码的任务 task collectUiCode(type: Copy) { // 清空临时目录 delete "${projectDir}/frontend-temp" mkdir "${projectDir}/frontend-temp/src" // 复制core的前端配置 from "${projectDir}/../core/src/main/ui" include "package.json", "vite.config.js", "index.html", "public/**" into "${projectDir}/frontend-temp" // 复制core的源码 from "${projectDir}/../core/src/main/ui/src" into "${projectDir}/frontend-temp/src" // 复制feature模块的源码 from "${projectDir}/../feature1/src/main/ui/src" into "${projectDir}/frontend-temp/src/feature1" from "${projectDir}/../feature2/src/main/ui/src" into "${projectDir}/frontend-temp/src/feature2" } // 配置任务执行顺序 tasks.named('npmInstall') { dependsOn collectUiCode } tasks.named('npm_run_build') { dependsOn npmInstall environment = ['NODE_ENV': 'production'] args = ['run', 'build', '--', '--outDir', '../src/main/resources/static'] } processResources.dependsOn npm_run_build
注意事项
- 前端代码要做好路径隔离:每个feature的ui代码存放在单独的子目录,配合vite/webpack配置alias,避免导入路径冲突
- 可以配置前端自动路由注册:在core的路由逻辑中自动扫描所有feature目录下的路由配置文件,自动合并到主路由,新增功能无需修改core模块代码
- 如果是前后端分离部署,只需要修改前端构建的输出目录,单独打包dist目录用Nginx托管即可,不用打到SpringBoot的jar包中
内容的提问来源于stack exchange,提问作者wojg21
相关产品推荐
相关产品推荐

