【问题标题】:Flask: How to use ES6 modules?Flask:如何使用 ES6 模块?
【发布时间】:2019-10-28 10:30:59
【问题描述】:

我有一个正在工作的 Flask 应用程序,我正在尝试重构它以使用 ES6 导入。我不需要它在旧浏览器上运行,而 ES6 导入在现代浏览器中也能正常工作,对吧?

我现在只是通过 Flask 的内置服务器运行它。生产应用程序是通过 gevent 提供的,但我显然还没有进行这些更改。

以下是我迄今为止尝试过的。我哪里出错了?

views.py

@app.route('/home')
def serve_home():
    return render_template('home.html')

格式化.js

export function formatNumber(...) {
  ...
}

尝试 1

home.html

<script type="text/javascript" src="/static/js/main.js"></script>

main.js

import {formatNumber} from "/static/js/formatting.js";

错误(main.js,第 1 行)

Uncaught SyntaxError: Unexpected token {

尝试 2

  • 将脚本类型更改为“模块”

home.html

<script type="module" src="/static/js/main.js"></script>

错误(main.js,第 1 行)

加载模块脚本失败:服务器以“text/plain”的非 JavaScript MIME 类型响应。根据 HTML 规范对模块脚本强制执行严格的 MIME 类型检查。

尝试 3

  • 将两个 Javascript 文件的扩展名从“js”更改为“mjs”

home.html

<script type="module" src="/static/js/main.mjs"></script>

main.mjs

import {formatNumber} from "/static/js/formatting.mjs";

错误(main.mjs,第 1 行)

加载模块脚本失败:服务器以“application/octet-stream”的非 JavaScript MIME 类型响应。根据 HTML 规范对模块脚本强制执行严格的 MIME 类型检查。

【问题讨论】:

    标签: javascript python flask es6-modules


    【解决方案1】:

    我很确定你需要使用 webpack 和 babel 来转译你的代码。

    有一个 Flask 的 webpack 插件可能有用https://pypi.org/project/Flask-Webpack/https://github.com/nickjj/flask-webpack

    您也可以按照此https://itnext.io/a-template-for-creating-a-full-stack-web-application-with-flask-npm-webpack-and-reactjs-be2294b111bdhttps://codeburst.io/creating-a-full-stack-web-application-with-python-npm-webpack-and-react-8925800503d9 教程进行操作。忽略关于 react 的部分

    这篇ES6 build chain python backend (flask) not SPA 的帖子似乎也与您的相似。

    【讨论】:

      【解决方案2】:

      我不需要它在旧浏览器上运行,而 ES6 导入可以在现代浏览器中运行而无需转译,对吧?

      这取决于您的预期应用程序用户的浏览器范围。

      在现代网络浏览器中支持 ES6 导入。

      请参阅list of supported browsers 以确保您在受支持的浏览器版本中查看您的应用程序。

      脚本扩展名应该是.js,而不是上面链接中记录的.mjs

      我注意到报告的错误与 mimetype 有关。 Flask 是 returning an application/octet-stream 用于静态文件的 mimetype,它无法猜测 mimetype。

      您可以使用url_for 模板函数更正此问题,为指向返回适当mimetype 的视图的文件构建URL。

      <script type="module" src="{{ url_for('es6-static', filename='/js/main.js') }}"></script>
      
      @app.route('/es6-static/<path:filename>')
      def es6_static(filename):
          return send_from_directory(app.config['ES6_MODULES'],
                                     filename, as_attachment=True,
                                     mimetype='text/javascript'
          )
      

      虽然text/javascript 是 JS 资源的已弃用 mime/type,但您可能在浏览器中对它有更好的支持。

      我强烈建议使用 gunicorn 或 nginx 来提供静态文件,因为以上只是有助于开发。

      【讨论】:

        【解决方案3】:

        对于那些遇到错误的人:

        The server responded with a non-JavaScript MIME type [...]
        

        ...您需要确认 python 正在返回您的 JS 文件的预期 mimetype。

        >>> import mimetypes
        >>> mimetypes.guess_type("notExists.js")
        ('text/javascript', None)
        

        我自己使用 Windows 平台从(例如 Flask 的开发服务器)托管 Web 服务器,我发现我需要更新注册表以将文件扩展名与 text/javascript 关联。

        例如,在注册表编辑器中:

        1. 在 HKEY_CLASSES_ROOT 下,找到 .js(如果使用,则找到 .mjs
        2. 查看“内容类型”的值。它必须text/javascript,而不是text/plain,或application/octet-stream等。

        【讨论】:

          【解决方案4】:

          这对我有用:

          import mimetypes
          mimetypes.add_type('application/javascript', '.mjs')
          

          在启动烧瓶之前添加此代码

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-01-15
            • 2021-01-21
            • 1970-01-01
            • 2015-07-23
            • 2020-11-19
            相关资源
            最近更新 更多