Python中如何在后端代码(如uliweb)里嵌入纯前端代码(如Vue)进行开发?
我很不喜欢调试的时候后端和前端的调试服务器都开着,因为是两个端口还要搞跨域,所以试试直接在后端代码里嵌入纯前端的应用
大概做法是
- 把前端用 webpack 之类 build 出来的文件配置输出到后端能 serve 的 static 目录下
- 用 nodejs 里的 watch 监控前端源代码变化并 build
不好的地方:
- 感觉这种编译会稍慢一些,比前端的调试服务器用增量编译并用 websocket 传到页面慢不少
- static 文件会有缓存,所以调试的时候要强制刷新( ctrl+shift+r) 或者浏览器里禁用 cache
比较适合于我们这种本来是后端程序员,但是也想用纯前端开发的伪全栈
具体例子代码: https://github.com/zhangchunlin/node_in_uliweb_example
Python中如何在后端代码(如uliweb)里嵌入纯前端代码(如Vue)进行开发?
webpack 有 proxy table 解决跨域问题…
在Uliweb这类Python后端框架里嵌入Vue这样的纯前端代码,核心思路是把前后端分离:后端只提供API接口,前端通过HTTP请求获取数据。具体实现分两种情况:
情况一:简单页面,Vue直接内嵌 如果你的页面逻辑简单,可以直接在Uliweb的模板里写Vue代码:
# views.py
from uliweb import expose
@expose('/')
def index():
return {}
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<button @click="fetchData">获取数据</button>
<ul>
<li v-for="item in items">{{ item.name }}</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
items: []
},
methods: {
async fetchData() {
const response = await fetch('/api/data');
this.items = await response.json();
}
}
});
</script>
</body>
</html>
情况二:复杂应用,前后端完全分离 更推荐的方式是:
- Vue项目单独开发,用
npm run build生成静态文件 - 把
dist文件夹里的内容放到Uliweb的static目录 - Uliweb只负责API和静态文件服务:
# views.py
from uliweb import expose, json
@expose('/api/data')
def api_data():
data = [
{'id': 1, 'name': '项目A'},
{'id': 2, 'name': '项目B'}
]
return json(data)
@expose('/')
def index():
# 直接返回Vue构建的首页
from uliweb import settings
return redirect(settings.STATIC_URL + 'index.html')
# settings.ini 配置静态目录
[GLOBAL]
DEBUG = True
[FUNCTIONS]
static_files = 'uliweb.contrib.staticfiles'
关键点:
- 开发时:Vue用
npm run serve,Uliweb开API服务,通过CORS解决跨域 - 部署时:Vue构建的静态文件交给Uliweb的静态文件处理器
- 路由:Vue用history模式时,需要在Uliweb配置catch-all路由返回
index.html
总结建议:前后端分离,Uliweb只做API,Vue单独构建部署最清晰。
我配了个 nginx 来转发,主要是头一次配置的时候花些时间
我是前端,我会花 2 分钟配置 Nginx 转发
Laravel 就是这样做的…官方出了一套 mix 把 vue/react 之类的按需整合进去了
是说这个吗? https://laravel.com/docs/5.7/mix
看到了 watch,感觉像,但是看起来有点复杂不知道为什么
前后端分离的话就要把 proxy 解决掉,不然就用 ssr 来做。
不过也可以试试 next+egg 的思路
看过好几个这样搞的了,坏处是出来的东西都是一个样,耦合紧
看到 uliweb,想起年轻的时候,〒_〒
webpack 的 devserver 中的 proxy 了解一下?
你看 Rails 开发者就不用关心这些无聊的配置,rails server + bin/webpack-dev-server 运行一下就开干。
突然发现我好像写过这样的项目,vue build 完成以后拷贝到 springboot 的静态目录。
我这是另一个选择,不用折腾 proxy
你说的 ssr next egg 都不了解,有空了解下
为什么这样就会耦合紧?这只是调试部署上的调整,和具体开发关系不大
我也在研究这问题,感觉还是开发的时候分开,部署的时候打包到 static 里好,因为每次 static 更新都要重新编译。webpack 是有 proxy,但我用的 parcel。有没有用 parcel 的大佬说说怎么配代理吗
搞跨域不就是一个 CORS 的事情吗。。就算不用 webpack 的 proxy,自己手撸一个简单的代理或者带 CORS 的 mock server 做成 cli 放 npm script 里,一次撸完以后每次项目都能用到不是也很方便。。
“因为每次 static 更新都要重新编译” 不明白你说的是什么意思,我这里只要 build 输出到 static 目录下就行了
你是 python 吧?确实动态语言不需要。我是写 java 的,修改代码需要编译一下才能生效,有时候还得重启
这个和静态和动态语言没关系,而是和调试服务器的实现有关系吧,如果调试服务器不提前加载 static 文件列表,而是实时去取文件路径下的文件就不用重启
调试的时候跨域,但是部署的时候实际上不跨域,这样造成调试和部署的时候不一致,对这个我觉得很不舒服.
ci、cd 很麻烦,试过 build 慢死。。
ci cd 这方面没什么差别吧,都要从头 build
分开 build

