¿Cómo cargar una biblioteca en un componente de tema?

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

Hola @merefield – ¿Sigue siendo esta la forma de hacerlo?

Estoy intentando incorporar qrcode.js para generar un QRcode en el navegador.

Me está bloqueando CSP, y no entiendo cómo es un problema de CSP si está en el mismo host. Esto es en un servidor de producción que usa discourse_theme para depurar.

Estoy poniendo esto en un inicializador:

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

Y parece que la función no se llama para cargar el script si no llamo this.ensureQRCode();, lo cual parece que no haces en tu componente.

El script está disponible y puedo recuperarlo (así que tengo las cosas en about.json y /assets/qrcode.js bien), pero el navegador se niega a cargarlo.

2 Me gusta

El resultado de tu loadscript es una promesa, por lo que necesitas poner tu código que depende de ella en un bloque .then, como en mi código de ejemplo.

3 Me gusta

No sé si esto es algo similar (sospecho que no), pero me está volviendo loco porque esto debería ser fácil de hacer.

1 me gusta

¡Muchas gracias!

Pero pensé que había hecho eso:

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

Intenté cambiar tu ejemplo lo menos posible :slight_smile:

¿Quizás necesito usar un .then cuando intente usar el código más tarde?

Pero eso no resuelve el problema de CSP, ¿verdad?

image

2 Me gusta

Mis dos consejos principales son:

Poner la biblioteca en la carpeta de assets

Esto resuelve CSP, hace que el tema sea autónomo y se considera una buena práctica, en lugar de cargarlo de terceros.

Cargarlo perezosamente

Solo cuando sea necesario, puedes cargarlo perezosamente usando await loadScript. Esto significa que no se cargará en páginas donde no sea necesario, ralentizando todo tu sitio.


Un buen ejemplo de un tema que sigue estas buenas prácticas es GitHub - discourse/discourse-mermaid-theme-component

6 Me gusta

Sí, precisamente. :+1:. Así es como funciona en mi ejemplo.

3 Me gusta

Una pregunta más: ¿Cuál es la diferencia entre ...initializers/mycode.js y ...api-initializers/mycode.js?

¡Y muchas gracias a ambos!

¡Ese fue un buen ejemplo! Pude entenderlo.

Bueno, pensé que seguía tu ejemplo. Javascript todavía parece un laberinto retorcido de pasajes que todos se parecen.

3 Me gusta