基于springboot+vue的前后端分离后项目部署方案
在传统模式下,项目部署只可能是后端开发人员的事,与前端开发人员没有什么关系。而前后端分离后,可能会有些许改变。
常见的部署方案如下:
一、前后端一起部署,前端打包成静态文件,拷贝到后端项目中,然后部署后端项目。
二、前后端分开部署,前端使用nginx部署,后端单独运行,然后使用nginx反向代理。
三、前后端分开部署,前端扔在cdn,后端单独运行。
本文重点讲一下方案一和方案二,限定条件:路由模式-history
部署原理:
- 如果访问路径对应的文件存在,则返回对应文件;
- 如果访问路径对应的文件不存在,则返回index.html
部署方案一(springboot+vue)
- 后端新增控制器处理如下:
// 这里用到了模板引擎thymeleaf(当然,别的模板引擎也行)
@Controller
public class IndexController {
@GetMapping("/ui/**") // 所有的/ui/** 返回index.html页面
public ModelAndView ui() {
return new ModelAndView("/index.html");
}
@GetMapping("/") // 访问根目录,要转发到上面的请求
public ModelAndView index() {
return new ModelAndView("forward:ui");
}
}
注意:这里的/ui/主要是为了方便区分是否为前端路由,和前端的路由的base保持一致。
- 前端路由文件处理如下:
const router = new VueRouter({
base:"/ui/", // 这里要和控制层那里配置一致
mode:'history',
routes: [
{
path:'/',
name:'home',
component: () => import('@/views/home.vue')
},
{
path:'/about',
name:'about',
component: () => import('@/views/about.vue')
}
]
部署流程
- 将前端工程进行打包,生成文件在dist目录下
- 将前端打包的dist/**的所有文件(除index.html外)复制到src/main/resources/static目录下(springboot静态文件目录)
- 将前端打包的dist/index.html文件复制到src/main/resources/templates(模板引擎模板根目录)
- maven打包生成jar包
- 发布
这里推荐一个maven打包插件
<!--资源插件,主要为了从前端项目里复制打包好的文件到springboot项目-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy static</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/resources/static</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<!--因为vue-cli打包的目录在项目的根目录,所以从这里复制-->
<directory>/java_projects/${project.artifactId}/dist</directory>
<includes>
<include>css/</include>
<include>img/</include>
<include>fonts/</include>
<include>js/</include>
<include>favicon.ico</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy template</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/resources/templates</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<!--因为vue-cli打包的目录在项目的根目录,所以从这里复制-->
<directory>/java_projects/${project.artifactId}/dist</directory>
<includes>
<include>index.html</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
部署方案二(nginx+springboot+vue)
nginx配置如下:
server {
listen 80;
server_name localhost;
root /java_projects/project_name/dist; # 前端打包目录
location / {
try_files $uri $uri/ @router; # 存在文件,返回文件,不存在,由@router处理
index index.html;
}
location @router {
rewrite ^.*$ /index.html last; # 所有请求,返回index.html
}
location /api { # 为了访问统一处理,前端也要修改
rewrite /api/(.*) /$1 break; # 重写请求(后端并无/api前辍)
proxy_pass http://127.0.0.1:18080; # 接口地址
}
}
或者不重写,url加/
server {
listen 80;
server_name localhost;
root /java_projects/project_name/dist; # 前端打包目录
location / {
try_files $uri $uri/ @router; # 存在文件,返回文件,不存在,由@router处理
index index.html;
}
location @router {
rewrite ^.*$ /index.html last; # 所有请求,返回index.html
}
location /api/ { # 为了访问统一处理,前端也要修改
proxy_pass http://127.0.0.1:18080/; # 接口地址
}
}
前端修改如下:
axios.defaults.baseURL='/api'; // 该配置与nginx配置一致