Search code examples
djangoecmascript-6django-templateses6-modulesdjango-staticfiles

Django load ES6 javascript file


I would like to use the import feature in ES6 in index.html in django.

I do not want to compile to ES5 for browser compatibility. I would like to assume that all the users will have ES6 compatible browsers.

Therefore I do not need a ES6 to ES5 compiler such as Babel: https://github.com/kottenator/django-compressor-toolkit

I simply would like to serve the ES6 Javascript and the browser to compile it if it can.

I tried:

<!-- Index.html -->
<script type="module" src="{% static 'app.js' %}"></script>

//app.js
(function(){
  console.log("Hello from App.js");
})();

# settings.py
if DEBUG:
    import mimetypes
    mimetypes.add_type("module", ".js", True)

The error I get:

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.


Update 1: I tried:

<script type="module" src="{% static 'app.js' %}"></script>
<script nomodule  src="{% static 'app.js' %}"></script>
<script type="module">import "{% static 'main.mjs' %}";</script>

https://developers.google.com/web/fundamentals/primers/modules


Update 2: Is it possible NOT to use a precompiler?

enter image description here

https://github.com/kottenator/django-compressor-toolkit

Update 3: I found

https://module-script-tests-sreyfhwvpq.now.sh/mime

enter image description here enter image description here

And this is what I have: enter image description here

I use Chrome: Google Chrome is up to date Version 71.0.3578.98 (Official Build) (64-bit)

Update 4: I would like to use

<!-- index.html -->
<script type="module"> instead of <script type="text/javascript">

because I want to be able to import modules:

<!-- index.html -->
<script type="application/javascript" src="{% static 'app.js' %}"></script>

//app.js
import { print } from "{% static 'component.js' %}"

currently gives error:

Uncaught SyntaxError: Unexpected token {


Update 5:

This is my file structure:

Update 5:

This is my Index:

{% extends 'base.html' %}
{% block content %}
{% load static from staticfiles %}
<h1>Index</h1>
{% include 'component.html' %}
<script type="module" src="{% static 'app.js' %}"></script>
{% endblock %}

This is my base.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Index</title>
    {% load static from staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
</head>
<body>
    {% block content %}
    {% endblock %}
</body>
</html>

This is my app.js:

import {A} from "./component.js"
console.log("A" + A)

This is my component.js:

export const A = 42

This is the error I still get:

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.

This is what I get for content type:

enter image description here


Solution

  • I finally got it working.

    This is what I needed to add to the settings.

    if DEBUG:
        import mimetypes
        mimetypes.add_type("application/javascript", ".js", True)
    

    The mistake I was making was that I was refreshing but no clearing cache while I was debugging.

    If you debug network stuff always make sure to ctrl+F5 when you test.

    enter image description here

    If I comment the mimetype:

    if DEBUG:
        import mimetypes
        #mimetypes.add_type("application/javascript", ".js", True)
    

    Then I get the error:

    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.

    And I see this:

    enter image description here