Come caricare una library in un theme component

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

Ciao @merefield – È ancora questo il modo per farlo?

Sto cercando di importare qrcode.js per generare un QRcode nel browser.

Vengo bloccato da CSP e non capisco come possa essere un problema di CSP se è sullo stesso host. Questo è su un server di produzione che usa discourse_theme per il debug.

Sto inserendo questo in un initializer:

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"
        // );
...

E sembra che la funzione non venga chiamata per caricare lo script se non chiamo this.ensureQRCode();, cosa che tu non sembri fare nel tuo componente.

Lo script è disponibile e posso recuperarlo (quindi ho fatto bene con le cose in about.json e /assets/qrcode.js), ma il browser si rifiuta di caricarlo.

2 Mi Piace

Il risultato del tuo loadscript è una promise, quindi devi inserire il tuo codice che si basa su di essa in un blocco .then come nel mio codice di esempio.

3 Mi Piace

Non so se sia una cosa simile (sospetto di no) ma mi sta facendo impazzire perché dovrebbe essere semplice da fare.

1 Mi Piace

Molte grazie!

Ma pensavo di averlo fatto:

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

Ho provato molto a cambiare il tuo esempio il meno possibile :slight_smile:

Forse devo usare un .then quando cerco di usare il codice in seguito?

Ma questo non risolve il problema CSP, vero?

image

2 Mi Piace

I miei due consigli principali sono:

Metti la libreria nella cartella degli assets

Questo risolve CSP, rende il tema autonomo ed è considerata una buona pratica, invece di caricarlo da terze parti.

Caricalo pigramente

Solo quando necessario, puoi caricarlo pigramente usando await loadScript. Ciò significa che non verrà caricato nelle pagine in cui non è necessario, rallentando l’intero sito.


Un buon esempio di tema che segue queste buone pratiche è GitHub - discourse/discourse-mermaid-theme-component

6 Mi Piace

Sì, precisamente. :+1:. È così che funziona nel mio esempio.

3 Mi Piace

Un’altra domanda: qual è la differenza tra ...initializers/mycode.js e ...api-initializers/mycode.js?

E grazie mille a entrambi!!

Quello era un buon esempio! Sono riuscito a capirlo!

Beh, pensavo di aver seguito il tuo esempio. Il Javascript sembra ancora un labirinto tortuoso di passaggi che sembrano tutti uguali.

3 Mi Piace