Comment charger une bibliothèque dans un composant de thème

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

Salut @merefield – Est-ce toujours la façon de faire ?

J’essaie d’intégrer qrcode.js pour générer un QRcode dans le navigateur.

Je suis bloqué par CSP. Je ne comprends pas comment il s’agit d’un problème CSP si c’est sur le même hôte. Ceci est sur un serveur de production utilisant discourse_theme pour le débogage.

Je mets ceci dans un initialiseur :

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

Et il semble que la fonction ne soit pas appelée pour charger le script si je n’appelle pas this.ensureQRCode();, ce que vous ne semblez pas faire dans votre composant.

Le script est disponible et je peux le récupérer (donc j’ai bien mis les éléments dans about.json et /assets/qrcode.js), mais le navigateur refuse de le charger.

2 « J'aime »

Le résultat de votre loadscript est une promesse, vous devez donc placer votre code qui en dépend dans un bloc .then, conformément à mon exemple de code.

3 « J'aime »

Je ne sais pas si c’est similaire (je soupçonne que non), mais bon sang, ça me rend fou parce que cela devrait être simple à faire.

1 « J'aime »

Merci beaucoup !

Mais je pensais avoir fait ça :

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

J’ai essayé de changer votre exemple le moins possible :slight_smile:

Peut-être que je dois utiliser un .then quand j’essaie d’utiliser le code plus tard ?

Mais cela ne résout pas le problème CSP, n’est-ce pas ?

image

2 « J'aime »

Mes deux conseils principaux sont :

Placer la bibliothèque dans le dossier des assets

Cela résout le problème CSP, rend le thème autonome et est considéré comme une bonne pratique, au lieu de le charger à partir de tiers.

Le charger paresseusement

Uniquement lorsque c’est nécessaire, vous pouvez le charger paresseusement en utilisant await loadScript. Cela signifie qu’il ne sera pas chargé sur les pages où il n’est pas nécessaire, ce qui ralentira l’ensemble de votre site.


Un bon exemple de thème qui suit ces bonnes pratiques est GitHub - discourse/discourse-mermaid-theme-component

6 « J'aime »

Oui, précisément. :+1:. C’est comme ça que ça marche dans mon exemple.

3 « J'aime »

Une autre question : Quelle est la différence entre ...initializers/mycode.js et ...api-initializers/mycode.js ?

Et un grand merci à vous deux !!

C’était un bon exemple ! J’ai pu le comprendre !

Eh bien, je pensais avoir suivi votre exemple. Javascript me semble toujours être un dédale de passages qui se ressemblent tous.

3 « J'aime »