Flask:如何使用 ES6 模块?
Posted
技术标签:
【中文标题】Flask:如何使用 ES6 模块?【英文标题】:Flask: How to use ES6 modules? 【发布时间】: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 类型检查。
【问题讨论】:
【参考方案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-be2294b111bd 或https://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
关联。
例如,在注册表编辑器中:
-
在 HKEY_CLASSES_ROOT 下,找到
.js
(如果使用,则找到 .mjs
)
查看“内容类型”的值。它必须说text/javascript
,而不是text/plain
,或application/octet-stream
等。
【讨论】:
【参考方案4】:这对我有用:
import mimetypes
mimetypes.add_type('application/javascript', '.mjs')
在启动烧瓶之前添加此代码
【讨论】:
以上是关于Flask:如何使用 ES6 模块?的主要内容,如果未能解决你的问题,请参考以下文章
如何判断一个特定模块是 CommonJS 模块还是 ES6 模块?