【问题标题】:How to get Flask to see Vue build files without using webpack?如何在不使用 webpack 的情况下让 Flask 查看 Vue 构建文件?
【发布时间】:2019-10-08 10:29:30
【问题描述】:

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

我正在尝试制作一个在前端使用 Vue 和 Vuetify 的简单 Flask 应用程序。当我查找如何将 Flask 与 Vue 结合的教程时(例如 one),它依赖于 webpack,我可以让它正常工作。当我尝试根据 Quick start guide 的说明将 Vuetify 添加到项目中时,我发现它要求您必须遵循 Existing Applications 指南,因为该项目未使用 vue-cli3 初始化(请参阅错误报告 here) .我尝试按照这些说明进行操作,但在几个令人困惑的小时后没有结果就放弃了。

在阅读了 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 吗?

提前致谢!

【问题讨论】:

    标签: vue.js flask webpack vuetify.js


    【解决方案1】:

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

    你应该使用 Flask-Webpack 来允许 flask 定位已经被散列和捆绑的资产。连同用于创建提供链接的清单 JSON 的 webpack 插件。使用flask 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 }), {})
          })
       })
    ]
    

    这将创建一个 manifest.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 模板将分开解耦,因此 {{ }} 交叉无关紧要,它们是上下文相关的。

    【讨论】:

    • 很好的答案,只是不是我想要的。我正在做的事情很愚蠢,以至于 Flask 不需要了解 webpack。话虽如此,如果我正在构建一个符合更传统用例的 Web 应用程序,我会全力以赴。
    【解决方案2】:

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

    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 Quick Start pageExisting Applications 部分的说明进行操作即可:

    main.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> index.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>
    

    最后在 index.js 的 build 部分更改 webpack 输出其构建的目录:

    // 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 文件。如果您将常规的 App.vue 和 HelloWorld.vue 文件替换为 Vuetify 文件,将 logo.svg 文件复制到 assets 文件夹并重新运行开发服务器,您将获得 Vuetify 登录页面。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-09
      • 2014-05-12
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 2017-03-20
      • 1970-01-01
      • 2010-10-13
      相关资源
      最近更新 更多