Laden einer Bibliothek in einer Theme-Komponente

from How to require external libraries in a component helper file? - #2 by merefield

Hallo @merefield – Ist das immer noch der richtige Weg, um das zu tun?

Ich versuche, qrcode.js einzubinden, um einen QR-Code im Browser zu generieren.

Ich werde durch CSP blockiert. Ich verstehe nicht, wie es ein CSP-Problem sein kann, wenn es sich auf demselben Host befindet. Dies geschieht auf einem Produktionsserver, der discourse_theme zum Debuggen verwendet.

Ich füge dies in einen Initialisierer ein:

import loadScript from "discourse/lib/load-script";
import { withPluginApi } from "discourse/lib/plugin-api";
// import QRCode from "discourse/lib/qrcode";
export default {
  name: "qrcode",
  ensureQRCode() {
    window.console.log(settings.theme_uploads.QRCode);
    return loadScript(settings.theme_uploads.QRCode).then(() => {
      return loadScript(settings.theme_uploads.QRCode);
    });
  },
  initialize(container) {
    withPluginApi("0.8.7", (api) => {
      api.decorateCookedElement((cooked, postWidget) => {
        const placeholderNodes = cooked.querySelectorAll(
          ".d-wrap[data-wrap=qrcode]"
        );
        this.ensureQRCode();
        // const qr = new QRCode(
        //   document.getElementById("qrcode"),
        //   "http://jindo.dev.naver.com/collie"
        // );
...

Und es scheint, dass die Funktion nicht aufgerufen wird, um das Skript zu laden, wenn ich this.ensureQRCode(); nicht aufrufe, was du in deiner Komponente anscheinend nicht tust.

Das Skript ist verfügbar und ich kann es abrufen (also habe ich die Sachen in about.json und /assets/qrcode.js richtig gemacht), aber der Browser weigert sich, es zu laden.

2 „Gefällt mir“

Das Ergebnis deines loadscript ist ein Promise, daher musst du deinen Code, der darauf angewiesen ist, in einem .then-Block platzieren, wie in meinem Beispielcode gezeigt.

3 „Gefällt mir“

Ich weiß nicht, ob das etwas Ähnliches ist (ich vermute nicht), aber es macht mich wahnsinnig, weil das einfach sein sollte.

1 „Gefällt mir“

Vielen Dank!

Aber ich dachte, ich hätte das getan:

    return loadScript(settings.theme_uploads.QRCode).then(() => {
      return loadScript(settings.theme_uploads.QRCode);
    });

Ich habe versucht, Ihr Beispiel so wenig wie möglich zu ändern :slight_smile:

Vielleicht muss ich .then verwenden, wenn ich den Code später benutze?

Aber das löst das CSP-Problem nicht, oder?

image

2 „Gefällt mir“

Meine zwei wichtigsten Ratschläge sind:

Legen Sie die Bibliothek in den Assets-Ordner

Dies löst CSP, macht das Theme in sich geschlossen und gilt als gute Praxis, anstatt es von Drittanbietern zu laden.

Laden Sie es verzögert

Nur wenn es benötigt wird, können Sie es verzögert mit await loadScript laden. Das bedeutet, dass es nicht auf Seiten geladen wird, auf denen es nicht benötigt wird, und Ihre gesamte Website verlangsamt.


Ein gutes Beispiel für ein Theme, das diese guten Praktiken befolgt, ist GitHub - discourse/discourse-mermaid-theme-component

6 „Gefällt mir“

Ja, genau. :+1:. So funktioniert es in meinem Beispiel.

3 „Gefällt mir“

Noch eine Frage: Was ist der Unterschied zwischen ...initializers/mycode.js und ...api-initializers/mycode.js?

Und vielen Dank an euch beide!!

Das war ein gutes Beispiel! Ich konnte es nachvollziehen!

Nun, ich dachte, ich hätte deinem Beispiel gefolgt. Javascript scheint immer noch ein verwirrender Irrgarten von Gängen zu sein, die alle gleich aussehen.

3 „Gefällt mir“