前一阵子有前端管理台的开发需求,而之前前端涉及的较少,就找了一个现成的模版CoreUI,其中有ReactJS版本的模板,试了试就发现欲罢不能了。而后台为了开发便捷,还是选择了Spring Boot(其实还是选择Express玩JS全栈会更有意思)。
后续整理了一套基于maven和gradle的SpringBootReact开发模版示例,上传到了Github(SpringBootReactDemo),这次就来简单谈谈其中的具体实现。
首先在ReactJS开发的时候,使用“npm start”开启3000端口开始调试ReactJS,前端的JS请求后端数据的时候,由于后台使用SpringBoot开发,直接通过JS访问时会产生跨域问题,当然解决的方法很多,例如通过“Access-Control-Allow-Orgin”头域、JSONP等。但是在实际环境中,ReactJS资源打包后作为SpringBoot应用的静态资源部署时,并不会出现CORS问题,为此,最好能够将JS API后台接口请求发往3000端口后,再由3000端口转发至8080端口,好在Node提供了这个功能,且配置十分简单,只需要在pacakge.json中添加如下配置即可实现:
"proxy": "http://localhost:8080"
解决了开发的问题,接下来最重要的就是打包了,最好的就是无论通过Grale还是Maven打包,能够自动执行ReactJS App的编译,并将编译后的静态资源一并打包。首先需要确保你的机器上安装好了Node环境,最好是也安装了Yarn,这个就不赘述了,接下来就来看看Gradle和Maven实现ReactJS App的编译工作。
Gradle方式
build.gradle中的相关部分如下所示:
task npmBuild(type: Exec) {
workingDir = file(NODE_PROJ_DIR)
commandLine NODE_MANAGER, "run", "build"
}
task npmInstall(type: Exec) {
workingDir = file(NODE_PROJ_DIR)
commandLine NODE_MANAGER, "install"
}
task frontendAssemble(type: Copy, dependsOn: "npmBuild") {
def buildDir = file("$NODE_PROJ_DIR/build")
from buildDir
into "build/resources/main/static"
}
processResources.dependsOn 'frontendAssemble'
if (project.hasProperty("node.install")) {
npmBuild.dependsOn 'npmInstall'
}
其中NODE_PROJ_DIR和NODE_MANAGER变量的定义放在了gradle.properties中,如下所示:
NODE_PROJ_DIR=src/main/frontend
NODE_MANAGER=yarn
NODE_PROJ_DIR指定了前端ReactJS的目录,NODE_MANAGER表示ReactJS的管理打包工具,你也可以选择npm或cnpm,只需要确保已全局安装,并且修改该变量值即可。
通过如上配置,gradle打包时会运行相应的"yarn run build"进行编译,并将打包之后的资源文件放入SpringBoot的静态资源文件夹中:
gradle build
如果同时需要进行CommonJS依赖的更新,可以增加node.install参数在编译前指定运行yarn install
gradle build -Pnode.install
Maven方式
pom.xml中的相关部分如下所示:
<properties>
......
<node.manager>yarn</node.manager>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<workingDirectory>${basedir}/src/main/frontend</workingDirectory>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>node-build</id>
<goals>
<goal>exec</goal>
</goals>
<phase>compile</phase>
<configuration>
<executable>${node.manager}</executable>
<arguments>
<argument>run</argument>
<argument>build</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-frontend</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
<configuration>
<outputDirectory>target/classes/static</outputDirectory>
<resources>
<resource>
<directory>src/main/frontend/build</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>node-install</id>
<activation>
<property>
<name>node.install</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>node-install</id>
<goals>
<goal>exec</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<executable>${node.manager}</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
其中node.manager表示ReactJS的管理打包工具,你也可以选择npm或cnpm,只需要确保已全局安装,并且修改该变量值即可。通过如上配置,maven打包时会运行相应的"yarn run build"进行编译,并将打包之后的资源文件放入SpringBoot的静态资源文件夹中:
mvn package
如果同时需要进行CommonJS依赖的更新,可以增加node.install参数在编译前指定运行yarn install
mvn package -Dnode.install