Come installare i pacchetti npm in temi/plugin personalizzati

Ciao!

È possibile installare pacchetti npm (tramite package.json o simili) nei temi e nei plugin di Discourse? Stiamo cercando di riutilizzare alcuni componenti tra diverse applicazioni e questo potrebbe essere un ostacolo se non è possibile.

Grazie!

Potresti fare più o meno come facciamo noi nel core, ovvero aggiungere i pacchetti npm tramite package.json e poi copiare i file JS in una cartella del tema (ad esempio javascripts/discourse/lib/), ma non puoi importare i pacchetti direttamente da node_modules; non credo che funzionerebbe.

Supponendo di avere un codice JavaScript puro (come qualcosa che possiamo includere ed eseguire per supportare un componente web personalizzato) come questo, come posso eseguirlo con il tuo approccio? Quando lo copio e lo incollo in discourse/lib all’interno del mio tema, non funziona.

Immagino che non funzioni perché il codice “non viene chiamato al momento giusto?”, ad esempio non viene eseguito quando la pagina viene caricata e nell’ambiente del browser.

Inoltre, per fornire un contesto a tutti, se provo a utilizzare https://unpkg.com/ e a includerlo nell’intestazione, ottengo un errore come questo:

Dopo aver risposto al commento e trasmesso l’informazione in un’unica idea, ho risolto l’errore seguendo DISCOURSE_CDN_URL causes content security policy violations?

Disattivando l’impostazione content_security_policy

Sto ancora cercando di capire perché lo script non funzioni, dato che ho un altro errore, ma forse fino a ora può essere utile per qualcun altro.

Per tua informazione, l’errore che sto riscontrando è questo:

Ma lo script è stato caricato :man_shrugging:

Infine, per qualcuno all’interno della stessa quest. Funziona così:

  1. Disattivare l’impostazione content_security_policy
  2. Aggiungere esplicitamente lo script in modo programmatico (non utilizzando $.getScript né altri approcci).

Un esempio riassuntivo di ciò che funziona per me è (sostituisci web-component con ciò che ha senso nel tuo caso):

import { withPluginApi } from "discourse/lib/plugin-api";

let flag = false;

export default {
  name: "web-component",
  initialize() {
    withPluginApi("0.8", api => {
      api.onAppEvent("page:changed", () => {
        if (flag) return;

        addScript(
          "https://unpkg.com/web-component@0.0.1/dist/web-component/web-component.js",
          { defer: "", crossorigin: "anonymous" }
        );

        addWebComponent(
          "web-component",
          {
            id: "web-component"
          },
          `Ciao mondo`
        );

        flag = true;
      });
    });
  }
};

function addWebComponent(tag, attrs, content) {
  var component = document.createElement(tag);

  Object.keys(attrs).forEach(key => {
    component.setAttribute(key, attrs[key]);
  });
  component.textContent = content;

  document.body.appendChild(component);
}

function addScript(src, attrs) {
  var script = document.createElement("script");

  script.setAttribute("src", src);

  Object.keys(attrs).forEach(key => {
    script.setAttribute(key, attrs[key]);
  });

  document.body.appendChild(script);
}

Il modo migliore per farlo è aggiungere quell’URL specifico all’elenco consentito nelle impostazioni del sito content security policy script src o nel componente del tuo tema. Per ulteriori dettagli, consulta Mitigare gli attacchi XSS con Content Security Policy.

Inoltre, puoi import loadScript from "discourse/lib/load-script"; e utilizzarlo per caricare uno script esterno (invece di definire il tuo iniettore addScript).

Mi dispiace per aver riaperto questa discussione, ma è quella più pertinente che sono riuscito a trovare.
Sto cercando di aggiungere questo pacchetto in un plugin. Vorrei importarlo usando import { RadixDappToolkit, RadixNetwork } from '@radixdlt/radix-dapp-toolkit'

È disponibile anche su Yarn, che credo sia quello che usa Discourse, ma non credo di poterlo semplicemente aggiungere come dipendenza… posso?

Non sono sicuro di poterlo caricare semplicemente usando unpkg, dato che ha molte dipendenze. Quali opzioni ho? Qualsiasi suggerimento è apprezzato.

Mi scuso per la domanda generica, ma sono molto confuso. Grazie!