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提供更多優秀的功能。大家可以在使用的過程中自由選擇。