Laden von JS-Bibliotheken über register_asset

Ich habe bemerkt, dass JS-Dateien, die über register_asset durch Plugins hinzugefügt werden, als String an die eval-Funktion übergeben werden.

Das Problem mit eval ist, dass es das Objekt nicht in den globalen Bereich einfügt, wie hier diskutiert: https://stackoverflow.com/questions/4670805/javascript-eval-on-global-scope. Das ist jedoch entscheidend, um eine JS-Bibliothek nutzen zu können.

Genauer gesagt: Ich habe versucht, https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC.js in einem Plugin zu verwenden, aber die Funktionen sind in den Ember-Dateien nicht zugänglich.

Die Workaround-Lösung besteht darin, die Datei mit Webpack zu verarbeiten und libraryTarget auf umd zu setzen.

Viele Bibliotheken werden auf diese Weise verarbeitet, was anscheinend sofort funktioniert.

Ich bin zwar kein Experte auf diesem Gebiet, frage mich aber, ob es für Discourse sinnvoll wäre, die registrierten Assets in den globalen Bereich einzubringen.

Hinweis: Entschuldigung, falls dies teilweise albern klingt. Ich habe nicht erwartet, dass ich mit Webpack herumspielen muss, um JS-Bibliotheken in Discourse zum Laufen zu bringen – das war der Auslöser für diesen Beitrag. :wink:

Etwas scheint hier nicht zu stimmen – ich habe unser lazyYT-Plugin angesehen, das ein Asset über register_asset einbindet, und es befand sich nicht in einem eval-Block.

Könntest du bitte ein kleines Beispiel-Plugin bereitstellen, das das Problem reproduziert?

Ich frage mich, ob dies eine unbeabsichtigte Nebenwirkung von

ist (d. h. dies tritt nur in der Entwicklungsumgebung auf).

Das habe ich mich auch gefragt – falls das der Fall ist, gibt es Workarounds, aber ich hätte gerne ein reproduzierbares Beispiel.

Klar.

Interessant. Ich kann das Plugin in der Produktion ausführen, um zu prüfen, ob das der Fall ist.

@eviltrout
Ein kleines Plugin, das dieselbe Bibliothek verwendet, die im OP erwähnt wird: GitHub - fzngagan/js-test · GitHub

Ich habe einfach versucht, die von der Bibliothek hinzugefügte Funktion im Initialisierer aufzurufen, und in der JS-Konsole erhalte ich ReferenceError: RecordRTC is not defined.

Ich habe die nicht-minifizierte Version der Bibliothek verwendet, was möglicherweise hilfreich für das Debugging ist.

Außerdem ein Screenshot aus dem Tab „Sources“, der zeigt, dass das gesamte Ding an die Funktion eval übergeben wurde.

Ein weiterer Befund meinerseits ist, dass die enthaltenen JS-Dateien sowohl in discourse-spoiler-alert als auch in lazy-yt Funktionen in das globale jQuery-Objekt injizieren, aber keine Funktionen auf oberster Ebene deklarieren.

Ich habe mir dein Plugin angesehen und kann bestätigen, dass eval nur im Entwicklungsmodus vorhanden ist. Im Produktionsmodus wird es in den globalen Bereich eingefügt. Ich verstehe, dass das nicht ideal ist, aber ich denke auch nicht, dass Bibliotheken normalerweise ohne eine gewisse Unterstützung für Module (zum Beispiel UMD) verteilt werden sollten.

Mein Vorschlag wäre, das JS mit einer Art UMD-Unterstützung neu zu verpacken und es dann mit import zu laden. Das ist jedoch etwas kompliziert einzurichten, wenn du nicht viel Erfahrung mit JS-Modulen hast.

Stattdessen gibt es einen einfachen Weg, dies zum Laufen zu bringen: Bearbeite RecordRTC.js und füge folgende Zeile hinzu:

window.RecordRTC = RecordRTC;

Noch besser wäre es, den gesamten Inhalt in eine IIFE zu packen:

(function(exports) {
  // hier kommt der ursprüngliche Dateiinhalt hin
  exports.RecordRTC = RecordRTC;
})(window);

Ja, ich stimme zu. Viele davon werden so verteilt und funktionieren nahtlos. Danke, dass du dich damit befasst und die Bestätigung gegeben hast :+1: Ich habe mich für das Verpacken der Bibliothek über Webpack entschieden, und es funktioniert sogar ohne Import. Ich hätte es allerdings im Produktionsmodus testen sollen.