T-Rex: Javascript: "script type='module '" Was ist das?

Moin,

da steckt man ein paar Jahre in einem Projekt und ist mehr oder weniger abgeschottet von der Welt. Dann bekommt man einen Auftrag, dass man ein Javascript warten soll und dann ...

Das Javascript wird wie folgt eingebunden: <script type='module' src='./js/map-component.js'></script>

Einen type='module' hab ich bis dato noch nicht gesehen. Was ist das, was macht es? Laut selfhtml wiki hat es keinen Zweck.

In dem Script habe ich dann folgendes gefunden: class MapComponent extends HTMLElement Das class mittlerweile funktioniert ist super cool. Aber was ist HTMLElement und wo kommt das her? Da ist kein request, require oder ähnliches. Wozu braucht man das, was kann es?

Am Ende steht dann noch: window.customElements.define('map-component', MapComponent);

Das scheint wohl der Aufruf zu sein, da der constructor aufgerufen wird ohne das ich selbst ein new irgendwo stehen hab. Was ist das, was macht es?

Wenn ich selbst ein new versuche wird mir ein Fehler ausgegeben: "Illegal constructor". Das "super()" im constructor wird als falsch betrachtet. Daraus leite ich ab dass der define Aufruf den parent HTMLElement läd und erst dann die Klassen miteinander verbunden werden können. Mit einem simplen new scheint HTMLElement nicht bekannt zu sein und der extend funktioniert nicht richtig.

Danke. Gruß T-ype="Rex"

  1. Hallo T-Rex,

    die Quelle, die PL verlinkt, wäre auch meine gewesen.

    TL;DR: type="module" ist ein Feature von ECMAScript 6 (a.k.a. ECMAScript 2015), das erste Release des "Harmony" Projekts, das seit 2015 jährlich eine neue JS Version spezifiziert.

    Die Idee von Modulen gibt's schon länger. Unser Wiki hat da einen recht alten Stand, das "Revealing Module Pattern", in dem man das, was ES6 mit type=module bietet, noch per Hand baut.

    Es gibt auch diverse Javascript Libraries, wie z.B. require.js, die das Modulkonzept anbieten. Auch da musst Du Dich strikt an bestimmte Programmiermuster halten, damit das funktioniert.

    Aber ES6 Module machen es im Prinzip genauso.

    • Ein Modul exportiert bestimmte Objekte. Das können einfach nur Objekte sein, aber auch Konstruktoren für Funktionen.
    • Ein Modul importiert optional andere Module und verwendet deren Exporte.
    • Was ein Modul NICHT exportiert, ist im Modul privat.
    • Genau wie bei klassischen Tools wie require.js gibt es Tools zum Bundling und Minifizieren von ES6 Modulen, damit eine Application, die aus 20 Modulen besteht, effizient geladen werden kann.

    Damit eine .js Datei (oder besser: .mjs) als Modul geladen wird, muss es mit type="module" geladen werden. Script, das ins HTML eingebettet ist, ist per Definition kein Modul, kann also keinen import verwenden kann also nichts exportieren. Ein inline-<script type="module"> ist aber möglich, um andere Module zu importieren

    Edit nach dem Hinweis aus der Unterwelt

    Wichtig ist auch, dass das Modul mit einem Javascript MIME-Typ geliefert wird, und dass man Module von fremden Sites nur importieren kann, wenn man seine Seite mit passenden CORS Headern ausliefert. Korollar: Eine von file:/// geladene HTML Seite kann keine Module laden. Denn file:/// Ressourcen sind nie same-origin, Und eine file:/// Ressource kann keine Header bekommen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf

      Script, das ins HTML eingebettet ist, ist per Definition kein Modul, kann also keinen import verwenden.

      Doch, Module können auch direkt ins HTML eingebettet werden und Objekte aus anderen Modulen importieren.

      // module.js
      
      export default 42
      
      <!-- index.html --><script type="module">
      
              import value from './module.js'
      
              document.querySelector('output').value = value
      
          </script>
        </head>
        <body>
          <output></output>
        </body>
      </html>
      

      Das gibt den importierten Wert aus.

      Viele Grüße

      1. Hallo Shadow,

        danke für den Hinweis.

        Als ich mich zuletzt mit Modulen befasst habe, hatte ich das anders verstanden. Entweder war ich dazu blöd, die Doku war falsch, oder es hat sich seitdem was geändert.

        Rolf

        --
        sumpsi - posui - obstruxi