Flask:如何使用ES6模块?

时间:2019-06-13 19:07:57

标签: javascript python flask es6-modules

我有一个正在工作的Flask应用,正在尝试重构以使用ES6导入。我不需要在旧的浏览器上运行它,而ES6导入可以在不进行编译的情况下在现代浏览器中工作,对吧?

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

以下是到目前为止我尝试过的。我在哪里弄错了?

views.py

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

formatting.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行)

  

未捕获的SyntaxError:意外令牌{

尝试2

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

home.html

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

错误(main.js,第1行)

  

无法加载模块脚本:服务器以非JavaScript MIME类型“ text / plain”响应。根据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行)

  

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

4 个答案:

答案 0 :(得分:3)

对于那些遇到错误的人:

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

...您将要确认python返回了您的JS文件的预期模仿类型。

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

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

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

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

答案 1 :(得分:2)

我敢肯定,您将需要使用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教程进行操作。只是忽略有关反应的部分

这篇文章ES6 build chain python backend (flask) not SPA似乎也和您的相似。

答案 2 :(得分:0)

  

我不需要在旧的浏览器上运行它,并且ES6导入可以在不进行编译的情况下在现代浏览器中工作,对吧?

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

在现代Web浏览器中,已记录了对ES6导入的支持。

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

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

我注意到报告的错误与mimetype有关。 Flask为returning an application/octet-stream,代表静态文件无法猜测其模仿类型的模仿类型。

您可以使用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 :(得分:0)

这对我有用:

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

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