前言
用python+flask写了个工具,后来又用react+antd+vite写了个web界面,采用前后端分离的方式.
项目只是个小工具,因为前后端分离导致启动后端项目以后还需要再通过node或nginx代理前端服务.这样很不方便,于是想到用python同时做前端服务器,这样便不需要再单独启前端服务了.
操作
1. 处理前端路由
编译后的前端路由在后端不能被代理,会404.看其他人的解决方案是通过flask将404跳转到首页.这里我是在前端动的手脚,使用react-router的MemoryRouter,不通过浏览器访问路由,浏览器的地址栏始终显示的是首页路由,弊端就是在任何页面刷新都会回到首页.
import { MemoryRouter, Route } from "react-router-dom"
function Router() {
return (
<MemoryRouter>
<Routes>
</Routes>
</MemoryRouter>
)
}
2. 将前端项目编译成静态文件
通过指定assetsDir,编译后会将静态文件都存放在assets目录下,后端路由配合转发assets资源文件 指定proxy,访问静态资源文件时,会将请求发给后端做代理
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
build:{
assetsDir: "assets",
},
plugins: [react()],
server: {
proxy: {
"/assets": {
target: 'http://localhost:5000/',
changeOrigin: true,
}
}
}
})
3. 将编译后的静态资源拷贝到后端目录下
通过tsc && vite build编译会产出dist/目录,将其拷贝到后端目录下
再修改flask默认静态资源路径
app = Flask(__name__, static_folder="dist")
4. flask代理首页
访问后端localhost:5000时,会将dist/index.html渲染出来
@app.route("/")
def index():
return app.send_static_file("index.html")
5. flask代理静态资源
渲染后的index.html会请求静态资源,这时通过步骤2的proxy又会请求后端接口,后端通过此接口便会将静态资源渲染出来,实现对前端资源的代理
# 静态资源
@app.route("/assets/<path>")
def assets(path):
return app.send_static_file("assets/" + path)