2014-07-03 6 views
5

Ich bin gewesen readingaboutes6 module loaders und ich verstehe einfach nicht ganz, wie es funktioniert und hoffe, dass jemand mich erleuchten kann.Wie funktioniert es6 Modul laden

In dem praktischen Workflows verknüpfen über sie ein Beispiel wie dieses

System.import('app/app').then(function(app) { 
    // app is now the Module object with exports as getters 
}); 

kein Problem damit haben - ich verstehe. Aber dann sehe ich Sachen wie diese

var $ = require('jquery'); 

und wirklich verwirrt werden. Was passiert, wenn jquery zum Zeitpunkt des Aufrufs noch nicht in den Browser übertragen wurde? Dreht sich der Thread nur? Analysiert der Browser das Skript hinter den Kulissen und wandelt es wie RequireJs in einen Callback um? Ist das konfigurierbar? Gibt es bestimmte Einschränkungen?

Kann mir jemand einen Überblick geben?

+1

Die zweite Sache, die Sie sehen, ist "CommonJS Modul laden", nicht ES6 afaik. In der Tat [funktioniert nicht (gut) in require.js] (http://requirejs.org/docs/api.html#cjsmodule) – Bergi

+0

@Bergi es funktioniert gut in require.js, während ich es nicht bevorzuge Es gibt bestimmte Seiten in meinem aktuellen Projekt, die requirjs mit dem commonjs-Stil verwenden. Requirejs scannt das Skript nach commonjs-Ausdrücken und schreibt es in ein amd-Format um, weshalb es immer noch Callbacks verwendet. Aber wenn ich mich nicht irre, verwendet der es6-Vorschlag KEINE Rückrufe - daher meine Verwirrung. –

+0

Ja, und das Scannen des Skripts funktioniert nicht für alle außer den einfachsten Fällen. Können Sie den Teil des ES6-Vorschlags, den Sie meinen, verlinken? 'System.import' verwendet offensichtlich Callbacks. – Bergi

Antwort

4

Der ES6-Modullader ruft die Quelle ab, ermittelt Abhängigkeiten und wartet, bis diese Abhängigkeiten geladen sind, bevor das Modul ausgeführt wird. Wenn die Anforderung ausgeführt wird, befindet sich die Abhängigkeit bereits dort und wartet darauf, ausgeführt zu werden.

Wenn wir CommonJS über einen ES6-Modullader laden, müssen wir statisch die require-Anweisungen von der Quelle analysieren und nur die Quelle ausführen, wenn diese benötigt wurden.

Auf diese Weise können wir CommonJS im dynamisch geladenen Browser unterstützen. Zirkelbezüge werden genauso behandelt wie im Knoten.

Die regulären Ausdrücke, die das Request analysieren, sind eigentlich ziemlich zuverlässig und schnell, wobei Kommentare und umgebende Tokens berücksichtigt werden. Siehe https://github.com/systemjs/systemjs/blob/master/lib/extension-cjs.js#L10 für den von SystemJS verwendeten.

Es gibt eine verbleibende Einschränkung mit diesem Ansatz und das ist dynamisch und bedingte CommonJS benötigt wie if (condition) require('some' + 'name') nicht richtig erkannt werden. Dies ist jedoch ein notwendiger Aufwand, um CommonJS als vollständig asynchrones Modulformat im Browser zu verhalten.

+1

Einige Zeit nachdem ich diese Frage geschrieben habe, haben wir [diesen tollen Artikel über es6 Module] (http://www.2ality.com/2014/09/es6-modules-final.html). Es widerspricht direkt etwas von dem, was Sie gesagt haben (zB Regex-Parsing, die Art, wie zirkuläre Abhängigkeiten funktionieren und die Verfügbarkeit von dynamischen erfordert). Es scheint auch, dass einige meiner Verwirrung zumindest darin besteht, dass Module und Modullader separate Spezifikationen sind, von denen nur die erstgenannte vollständig ist. –

+2

Der ES6 Module Loader hat zwei Möglichkeiten, Module zu interpretieren: 1. ES6-Module 2. Legacy-Modulformate Wir können das Legacy-Modulformat über einen Hook namens "Instanziieren" in den ES6-Modullader integrieren. Sie haben recht - ES6 Module laden hat auch einen eigenen zirkulären Referenzstil, der sich von CommonJS unterscheidet. Wenn CommonJS-Unterstützung in den Loader geschrieben wird, kann dies die vollständige Unterstützung von zirkulären Referenzwerten nach CommonJS-Art ermöglichen. In Bezug auf die Spezifikationen, ist das Modul Lader Klasse Verhalten selbst in der ES6-Spezifikation, was eine separate Spezifikation ist die genaue Umgebung Haken. – guybedford