如何让 Flask 在不使用 webpack 的情况下查看 Vue 构建文件



我对 Vue 和现代 Web 开发很陌生,所以我提前道歉。情况是这样的。

我正在尝试制作一个简单的 Flask 应用程序,它在前端使用 Vue 和 Vuetify。当我查找如何将 Flask 与 Vue 结合的教程时(就像这个),它依赖于 webpack,我可以让它正常工作。当我尝试根据他们的快速入门指南的说明将 Vuetify 添加到项目中时,我发现它要求您遵循Existing Applications指南,因为该项目不是使用 vue-cli3 初始化的(请参阅此处的错误报告)。我尝试按照这些说明进行操作,但在混乱的几个小时后放弃了,没有结果。

在阅读了 webpack 之后,我决定对于我的特定应用程序,我可以负担得起不使用它。所以我回到了 Vuetify 快速入门指南并按照New Applications说明,启动了 Flask,这就是我得到的:

127.0.0.1 - - [21/May/2019 18:31:20] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2019 18:31:20] "GET /js/app.c12f4ec0.js HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:31:20] "GET /css/chunk-vendors.b7bc2226.css HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:31:20] "GET /js/chunk-vendors.2eb58769.js HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:31:21] "GET /js/app.c12f4ec0.js HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:38:22] "GET /index.html HTTP/1.1" 404 -

有问题的代码:

from flask import Flask, render_template
app = Flask(__name__,
static_folder="./test/dist",
template_folder="./test/dist")
@app.route('/')
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)

在大多数情况下,Vue 代码只是一个安装了 Vuetify 的新项目。我所做的唯一更改是在main.js中,我更改了分隔符的内容,以便它们不会与 Jinja2 冲突。

import Vue from 'vue'
import './plugins/vuetify'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
delimiters: ["[[", "]]"],
}).$mount('#app')

我的三个主要问题是:

  1. Flask 用于查找静态文件和模板文件的路径有什么问题?
  2. 是否可以在没有 webpack 的情况下将 Vue 与 Flask 一起使用?
  3. 如果不可能,有人会做一个关于如何将 Vuetify 集成到基于 webpack 的 Vue 项目中的 eli5 吗?

提前感谢!

好的,所以我找到了答案,结果证明它比我想象的要容易得多。为了更容易复制我的步骤,我将从顶部开始。

app.py

from flask import Flask, render_template
app = Flask(__name__,
static_folder="./test/dist", # place that webpack builds to
template_folder="./test/dist")
@app.route('/')
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)

在与app.py相同的目录中运行以下命令(假设您已经安装了 vue-cli):

$ vue init webpack vue-app-name
$ cd vue-app-name
$ yarn add vuetify # or use npm install vuetify --save

现在你基本上只需按照 Vuetify 快速入门页面的Existing Applications部分的说明进行操作:

主顶部.js

import Vue from 'vue'
import App from './App'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css' // Ensure you are using css-loader

Vue.config.productionTip = false
Vue.use(Vuetify)

<head>索引部分.html

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>frontend</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons' rel="stylesheet">
</head>

最后在索引的构建部分.js将 web pack 输出其构建的目录更改为:

// Template for index.html
index: path.resolve(__dirname, '../../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../../dist'),

此时,如果您运行

$ yarn build # or npm run build
$ cd ..
$ python app.py

并弹出打开你的网络浏览器,你应该看到默认的 Vue HelloWorld 页面,你有 Flask 与 Vue、Vuetify 和 webpack 一起工作。

这就是我感到困惑的地方。如果您按照新 Vuetify 项目的说明运行开发服务器,它们将拥有自己的自定义 Hello World 页面。但是,因为 Hello World 页面仍然是默认的 Vue 页面,我认为这意味着没有安装 Vuetify。真正发生的事情是他们有不同的App.vue和HelloWorld.vue文件。如果你用Vuetify文件替换常规的App.vue和HelloWorld.vue文件,将logo.svg文件复制到assets文件夹中并重新运行开发服务器,你将获得Vuetify登陆页面。

无论如何,我觉得自己像个白痴,但希望这对另一个 Flask/Vue/Vuetify/Webpack 新手有所帮助。

这是使用 python 3.7.3和 vue-cli 3.7.0 完成

的。

我有多个 Vue 和 Flask 项目,发现 webpack 是最好的方法。我不喜欢 Vue-CLI,因为在构建时指定本地文件和捆绑文件的路径太困难了。我知道一开始这是一个学习曲线,但如果你投入时间,值得一两天。

您应该使用 Flask-Webpack 来允许 flask 查找已散列和捆绑的资产。以及一个 webpack 插件来创建提供链接的清单 JSON。使用烧瓶 webpack 时,您还需要像以前一样直接指定文件夹路径。

我的 webpack 配置中有这个设置:

const ManifestPlugin = require('webpack-manifest-plugin')
...
plugins: [
new ManifestPlugin({
writeToFileEmit: true,
seed: {
publicPath: '/'
},
generate: (seed, files) => ({
...seed,
'assets': files.reduce((manifest, { name, path }) => ({ ...manifest, 
[name]: path }), {})
})
})
]

这将创建一个如下所示的清单.json文件:

{"assets":{"base_css.css":"static/css/base_css.1bf3ff18.css",
"base_css.js":"static/js/base_css.1e6b291b.js",
"chunk-vendors.js":"static/js/chunkvendors.f92da40c.js",},
"publicPath":"/"}

设置好项目后,我设想在使用 npm 和导入添加到现有项目之后添加 Vuetify 是相当简单的。

请注意,使用 Vue-CLI 和/或 webpack 时,您无法更改 vue 分隔符。来自 API 文档中的分隔符:"限制:此选项仅在完整版本中可用,具有浏览器内编译。

但是最后一点应该不是问题,因为你的 html 模板和 vue 模板将分别解耦,所以 {{ }} 交叉无关紧要,它们是上下文相关的。

我遇到了类似的问题。@clayton-ramstedt 提供的答案提供了 200 个状态代码,但它加载的是空白页面而不是所需的静态 UI。原因是索引.html引用了其他各种JS和CSS文件,并且上面的答案对所有文件都返回了index.html

下面的代码对我有用。

from flask import Flask, send_from_directory
import os
app = Flask(__name__,
static_folder="./test/dist",
template_folder="./test/dist")
@app.route("/", defaults={"path": ""})
@app.route("/<path:path>")
def serve_frontend(path):

if path != "" and os.path.exists(app.static_folder + '/' + path):
return send_from_directory(app.static_folder, path)
return send_from_directory(app.static_folder, 'index.html')
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)

这将正确呈现JS和CSS文件,当我们遇到其他一些路由(如/login或/dashboard)时,它们将由index相应地处理.html。

确保提供path转换器类型,因为默认字符串类型不会呈现包含斜杠的 JS 和 CSS 文件。

相关内容

最新更新