Spring Boot與React集成在同一個項目實現腳手架

TL;DR

直接開箱即用的腳手架代碼:https://github.com/zclhit/myScaffold

前言

最近在考慮重新搭建自己的項目開發腳手架,我給這套腳手架的定義的期望是:足夠高的集成度與足夠簡潔,滿足快速上手開發與快速產出的要求。考慮到這些期望,我選擇了Spring Boot作爲後端實現框架,而前端,作爲2019年stack over flow most loved framework的票王,我選擇了React.js。

環境搭建

這個項目會依賴於Jdk1.8,node 8和npm 6進行展示,在此之前請確保你已經安裝了上述依賴到當前的開發環境。

創建Spring Boot with web

通過IntelliJ IDEA自帶的Spring Boot生成器生成web項目,File - New - project… - Spring Initializer (NEXT),設置好座標名、項目名稱,打包方式,Java版本,項目描述等信息。

在這裏插入圖片描述
在選擇項目依賴時,勾選Spring Web,這時將會自動將spring-boot-start-web依賴添加到項目中。spring-boot-start-web提供了開發一個Spring boot web所需要的絕大多數依賴,可以省下很多時間去做一些自己的設置和增加額外的依賴。

在這裏插入圖片描述

可以看到,初始化之後的文件結構如圖所示,所有的業務邏輯代碼都在src/main/java目錄下,所有的配置信息與靜態文件都在resource下,所有的測試文件都在src/main/test目錄下,由於我選擇的是maven作爲項目管理工具,所以mvnw, mvnw.cmd和pom.xml會出現在這個目錄下。

在這裏插入圖片描述

至此,一個基本的Spring Boot with Web就完成了。

把React引入進來

爲了把react引入進來並且方便後續(可能的)前後端分離操作,同時提供更好的前後端本地調試體驗,我們通過create-react-app的方式來完成,需要使用npm先安裝create-react-app:

npm install -g create-react-app

安裝成功後,我們通過create-react-app來初始化react app,在src目錄下執行:

create-react-app web

配置frontend-maven-plugin

這裏我們使用frontend-maven-plugin插件來實現項目打包時直接把build得到的前端文件放到Spring Boot使用的相關目錄下,這樣Spring Boot項目啓動後可以直接訪問到前端頁面。

首先向pom.xml文件中添加frontend-maven-plugin插件:

<plugins>
  <plugin>
    <!-- https://mvnrepository.com/artifact/com.github.eirslett/frontend-maven-plugin -->
      <groupId>com.github.eirslett</groupId>
      <artifactId>frontend-maven-plugin</artifactId>
      <version>1.6</version>
  </plugin>
</plugins>

同時配置maven-plugin插件在執行階段設置一系列行爲去安裝node和npm,執行npm install和npm run-script build。

<executions>
  <execution>
     <id>install node and npm</id>
     <goals>
       <goal>install-node-and-npm</goal>
     </goals>
     <configuration>
       <nodeVersion>v8.11.1</nodeVersion>
       <npmVersion>5.6.0</npmVersion>
       <nodeDownloadRoot>http://npm.taobao.org/mirrors/node/</nodeDownloadRoot>
       <npmDownloadRoot>http://npm.taobao.org/mirrors/npm/</npmDownloadRoot>
       </configuration>
   </execution>
   <execution>
     <id>npm install</id>
     <goals>
        <goal>npm</goal>
     </goals>
     <configuration>
        <arguments>install</arguments>
      </configuration>
   </execution>
 
   <execution>
     <id>npm run-script build</id>
     <goals>
       <goal>npm</goal>
     </goals>
     <configuration>
       <arguments>run-script build</arguments>
     </configuration>
    </execution>
 </executions>
 <configuration>
   <installDirectory>target</installDirectory>
   <workingDirectory>web</workingDirectory>
 </configuration>

其中配置選項中的installDirectory制定了node和npm的安裝路徑,在jar包中實現npm和node的安裝可以很好解決在沒有node和npm的機器上仍然能夠運行,當然如果這臺機器已經安裝了node和npm,就會屏蔽掉全局設置而使用包內部的node和npm。

workingDirectory制定了前端項目package.json文件所在的路徑,插件會自動在workdingDirectory路徑下執行npm install和npm run-script build的命令。

可以看到用frontend-maven-plugin可以很好解決目標機器上沒有npm和node的場景,但是在CI/CD場景下,這種做法會每次都重複安裝node與npm,不適合持續集成,所以如果能保證打包機器安裝了npm和node,可以去掉install node and npm這一步。

配置webpack

爲了能夠使用webpack,我們在package.json中增加以下的devDependencies:

"clean-webpack-plugin": "^3.0.0",
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"webpack-merge": "^4.2.2"

添加完成之後,記得去web目錄下執行npm install安裝最新的依賴。

之後在web目錄下創建build目錄,在build目錄中進行webpack的相關配置。這裏針對dev環境和prod環境進行不同的配置,由於dev環境下我們會直接使用npm start暴漏3000端口並轉發至localhost:8080端口進行本地前後端聯調,所以需要在本地進行devServcer的配置:

devServer: {
        port: '3000',
        contentBase: path.join(__dirname, '../dist'),
        compress: true,
        hot: true,
        proxy: {
            '/*': {
                target: 'http://localhost:8080'
            }
        }
    }

同時,在package.json中指定不同的script來實現不同的行爲:

"scripts": {
    "dev": "webpack-dev-server --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "webpack --config build/webpack.prod.conf.js"
  },

比如,我們經常通過npm start來啓動一個本地服務,那麼就可以讓他執行dev,然後走webpack.dev.con.js中的設置,啓動一個本地服務,proxy到本地的8080端口。

而在生產環境打包的過程中我們可以能需要npm run build,那麼我們可以讓它走webpack.prod.conf.js中的邏輯,把相應的包打包到Spring Boot的template或者static路徑下,這樣Spring Boot在啓動之後就可以直接訪問通過React編寫好的頁面。

後記

我把sprint-boot-starter-web之外增加了spring-boot-starter-thymeleaf,因爲我認爲thymeleaf提供更多優秀的功能。大家可以在使用的過程中自由選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章