前言
最近前端用Vue做了一个单页面应用app,用Django做了一个数据API服务器。开发到了一定程度之后,想要把Vue部署到服务器上与Django一起做联合开发和测试。
1. 前端Vue部分
前端Vue开发完成之后,就可以对开发文件进行打包,Vue脚手架默认已经配置了打包的脚本指令,使用npm run build
即可将开发文件打包成部署文件。打包前也可以先根据自己后端Django的需求,对打包过程进行一些配置。vue-cli3/4在vue.config.js
文件增加publicPath
或者是assetsDir
等设置。
先增加配置再打包(也可以按默认配置直接打包)
为了方便,打包前先添加一些配置:
module.exports = {
// publicPath可以根据该app相对域名的访问路径,默认为空,即可以直接通过域名访问,后续路由也以此做相对路径
outputDir: 'frontvue/', // 默认为dist
// outputDir: 'D:/xxx/DjangoProject/front/frontvue'
// 注意目录索引符 "/" 和 "\"("\\") 可以混合使用,但尽量不要。
assetsDir: 'static/', // 相对于outputDir(默认为项目根目录的dist)将js/css/img等文件打包的输出路径
// 注意:写相对路径时前面不能加“/”,否则webpack打包时会报错,会被识别成绝对路径。
// 设置后使用打包的静态资源都在dist/static文件夹下
...
indexPath: ""
...
/* 注意: 以上配置也可以设置绝对路径,来指定打包的输出位置。*/
}
运行npm run build
,在dist目录下(或者指定的Django工程目录)输出index.html,favicon.ico,static文件(夹),在static目录下有js/css/img等文件
2. 后端Django部分
由于前后端分离,前端Vue打包之后的文件都可以视为是静态(static)资源文件来响应处理。当然,index.html文件也可以使用传统的html模板的形式对前端请求进行响应。
可以在Django项目里新建一个文件夹来存储前端vue的打包文件,也可以直接在django目录下创建vue项目然后直接打包。但是要注意到整体目录结构要有层次。
更改django配置(django2.2)时,首先将settings.py
中TEMPLATES
的相关设置DIR
指定到index.html
所在的目录,从而可以直接在主项目的urls.py
或者其它子应用的urls.py
里添加路由:
# settings.py
TEMPLATES = [
{
...,
'DIRS': [os.path.join(BASE_DIR, 'front', 'frontvue')],
# front用来存放前端相关文件,frontvue为vue打包文件的目录
...
}
# urls.py
from django.views.generic import TemplateView
# 以TemplateView为例
urlpatterns = [
path('', TemplateView.as_view(template_name='index.html')),
# index.html请求入口
...
...
]
之后,就是静态文件的配置了:
# settings.py
STATIC_URL = '/static/'
# 此处STATIC_URL为静态资源请求时的URL前缀,与前端vue打包后的懒加载文件请求的相对路径一致(assetsDir)
# 所以可以直接请求到资源
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'front', 'frontvue', 'static')]
# 指定静态文件所存放的文件,即收到"/static/xxx/xxx"的请求时应该在哪查找对应的资源文件
后序
这篇文章并没有考虑普适性,只是针对个人的情况进行了一次简单总结,个人在本地电脑开发,然后全部通过Git服务器推送自动完成远在程服务器的部署。
另外再记一点,基于Django的前后端分离,需要解决浏览器的跨域请求限制(CORS_ORIGIN_ALLOW
等)以及服务器的跨域请求验证(CorsMiddleware
,csrf_token
验证)。前者一般自己添加一下响应头的相应条目,或者使用corsheaders第三方中间件;后者一般是服务器设置cookie然后前端从cookies中获取csrf_token信息,或者直接粗暴地把CorsMiddleware关掉。
最后再说个题外话,浏览器一般对favicon.ico
图标默认是从根域名来请求,而由于Django对静态文件的配置,一般的方法请求需要有"/static/"前缀,Django可以采用django.contrib.staticfiles.views.serve
来直接响应:path('favicon.ico', serve, {'path': 'favicon.ico'})
,这种方法可以直接兼容到/static/favicon.ico
问题,其中的'path'
为STATIC_DIR
下的路径,不必重定向或者其它复杂的操作。