SpringBoot+vue2联合部署,混合部署
前端工程和后端工程目前是都是相对独立性的模式进行开发的。
打包机 只拥有maven,没有nodejs
软件工程场景:
- 前后端工程在同一个父工程下面,作为一个子工程存在,各自独立开发。
- 前端工程作为一个独立的目录存在于后端代码中,前端目录的根目录(例如front)与后端工程的src目录同级。--本文的例子采用的是这种模式。
打包发布场景:
- 不将前端单独打包发布至nginx服务器中。
- 服务器只能部署一个war包。--本文的例子采用的是这种模式。
当满足上述场景的时候,可以采用以下打包部署方案
- 优先将前端构建打包,将前端构建出的内容,copy至后端SpringBoot工程的webapp目录下。
- 在通过maven打包后端,这样就可以将前端资源打保进war中了。
实现
主要是在前端处理。
在前端工程中增加脚本,脚本调用入口在package.json
文件中。通过node调用文件copy的脚本。
json
{
...
...
"scripts": {
"build-copy": "vue-cli-service build && node src/utils/fileCopy.js"
},
...
...
}
fileCopy.js
先删除目标路径(后端工程中的前端文件的路径)下的内容,在将新生成的前端文件copy过去。
js
const fileUtil = require('./fileUtil')
// 目标文件夹
const staticDirectory = '../src/main/webapp/'
// 删除
fileUtil.deleteFolder(staticDirectory + "static")
fileUtil.deleteFile(staticDirectory + "index.html")
// 拷贝
fileUtil.copyFolder('./server/dist', staticDirectory)
console.log('文件拷贝成功!')
fileUtil.js
借助fs
模块进行文件操作。
js
const fs = require('fs')
/**
* 删除该路径下所有的内容
* @param path
*/
function deleteFolder(path) {
let files = []
if (fs.existsSync(path)) {
if (fs.statSync(path).isDirectory()) {
files = fs.readdirSync(path)
files.forEach((file) => {
const curPath = path + '/' + file
if (fs.statSync(curPath).isDirectory()) {
deleteFolder(curPath)
} else {
fs.unlinkSync(curPath)
}
})
fs.rmdirSync(path)
} else {
fs.unlinkSync(path)
}
}
}
/**
* 删除文件
* @param path
*/
function deleteFile(path) {
if (fs.existsSync(path)) {
if (fs.statSync(path).isDirectory()) {
deleteFolder(path)
} else {
fs.unlinkSync(path)
}
}
}
/**
* 复制路径下的内容到指定目录
* @param from
* @param to
*/
function copyFolder(from, to) {
let files = []
// 文件是否存在 如果不存在则创建
if (fs.existsSync(to)) {
files = fs.readdirSync(from)
files.forEach((file) => {
const targetPath = from + '/' + file
const toPath = to + '/' + file
// 复制文件夹
if (fs.statSync(targetPath).isDirectory()) {
copyFolder(targetPath, toPath)
} else {
// 拷贝文件
fs.copyFileSync(targetPath, toPath)
}
})
} else {
fs.mkdirSync(to)
copyFolder(from, to)
}
}
module.exports = {
deleteFolder,
deleteFile,
copyFolder
}
问题:
- 在管理代码上需要进行手动执行前端打包,容易忘记。
- 对本地开发环境需要同时支持特定版本的nodejs和npm。
打包机同时拥有maven和nodejs。
如果打包机同时拥有maven和nodejs。可以借助maven插件frontend-maven-plugin
进行一步打包。
xml
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
若需要使用这个插件,需要将软件工程,调整为,后端工程和前端工程平级,同属于一个父工程的子工程下面。在父工程的pom文件中,定义模块时,需要将前端模块顺序放在后端之前,这样做,主要是为了解决前后端的打包顺序问题。
java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
...
...
<modules>
<module>frontend</module>
<module>server</module>
</modules>
</project>
前端工程中需要增加一个pom文件。配置脚本
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
...
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.8.0</version>
<executions>
<!-- 检查是否安装node npm -->
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
</execution>
<!-- 执行脚本,删除node_modules和package-lock.json -->
<execution>
<id>npm run clean</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run clean</arguments>
</configuration>
</execution>
<!-- npm install -->
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install --registry=https://registry.npm.taobao.org</arguments>
</configuration>
</execution>
<!-- build 之后复制文件到 src/main/resource/static 下 -->
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run build-copy</arguments>
</configuration>
</execution>
</executions>
<configuration>
<nodeVersion>v10.24.1</nodeVersion>
<npmVersion>6.14.12</npmVersion>
<!-- node安装路径 -->
<installDirectory>${settings.localRepository}</installDirectory>
<!-- 前端代码路径 -->
<workingDirectory>${basedir}</workingDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
通过调用父工程的mvn clean install
即可。
问题:
-
首次安装 nodejs和npm会很慢。
-
打包机需要可以访问淘宝镜像。或者搭建本地镜像,将对应的node和npm安装包放进去才可以。