Reputation: 20881
I have a working Flask app that I'm trying to refactor to use ES6 imports. I don't need it to run on old browsers, and ES6 imports work in modern browsers without transpilation, right?
I'm just running this via Flask's built-in server at the moment. The production app is served via gevent instead, but I'm obviously not at that point with these changes yet.
Below is what I've tried so far. Where have I gone wrong?
views.py
@app.route('/home')
def serve_home():
return render_template('home.html')
formatting.js
export function formatNumber(...) {
...
}
home.html
<script type="text/javascript" src="/static/js/main.js"></script>
main.js
import {formatNumber} from "/static/js/formatting.js";
Error (main.js, line 1)
Uncaught SyntaxError: Unexpected token {
home.html
<script type="module" src="/static/js/main.js"></script>
Error (main.js, line 1)
Failed to load module script: The server responded with a non-JavaScript MIME type of "text/plain". Strict MIME type checking is enforced for module scripts per HTML spec.
home.html
<script type="module" src="/static/js/main.mjs"></script>
main.mjs
import {formatNumber} from "/static/js/formatting.mjs";
Error (main.mjs, line 1)
Failed to load module script: The server responded with a non-JavaScript MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.
Upvotes: 13
Views: 13205
Reputation: 962
this worked for me:
import mimetypes
mimetypes.add_type('application/javascript', '.mjs')
added this code before launching flask
Upvotes: 5
Reputation: 1363
For those of you getting the error:
The server responded with a non-JavaScript MIME type [...]
...you'll want to confirm python is returning the expected mimetype of your JS files.
>>> import mimetypes
>>> mimetypes.guess_type("notExists.js")
('text/javascript', None)
For myself, using a Windows platform to host the web server from (eg. Flask's development server), I found I needed to update the registry to associate the file extension with text/javascript
.
For example, in the registry editor:
.js
(and .mjs
if using that)text/javascript
, NOT text/plain
, or application/octet-stream
, etc.Upvotes: 7
Reputation: 38982
I don't need it to run on old browsers, and ES6 imports work in modern browsers without transpilation, right?
It depends on browser spectrum of your intended application users.
There is documented support for ES6 imports in modern web browsers.
See the list of supported browsers to be sure that you're viewing your application in a supported browser version.
The script extension ought to be .js
and not .mjs
as documented in the above link.
I noticed that the error reported is one that as to do with mimetype. Flask is returning an application/octet-stream
for the mimetype of the static file where it is unable to guess the mimetype.
You can correct this using the url_for
template function to build the url for the file pointing at a view that returns an appropriate mimetype.
<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'
)
While text/javascript
is a deprecated mime/type
for JS resources, you may have better support for it in browsers.
I strongly suggest to use gunicorn or nginx to serve the static files as the above is only goes as far as helping with development.
Upvotes: 1
Reputation: 568
I'm pretty sure you will need to use webpack and babel to transpile your code.
There is a webpack plugin for Flask that might be of use https://pypi.org/project/Flask-Webpack/ https://github.com/nickjj/flask-webpack
You could also follow this https://itnext.io/a-template-for-creating-a-full-stack-web-application-with-flask-npm-webpack-and-reactjs-be2294b111bd or https://codeburst.io/creating-a-full-stack-web-application-with-python-npm-webpack-and-react-8925800503d9 tutorials. Just ignore the parts about react
This post ES6 build chain python backend (flask) not SPA seems to be a similar one to yours as well.
Upvotes: 2