Como carregar biblioteca em um componente de tema

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

Olá @merefield – Isso ainda é como fazer isso?

Estou tentando importar qrcode.js para gerar um QRcode no navegador.

Estou sendo bloqueado pelo CSP também. Não entendo como é um problema de CSP se está no mesmo host. Isso está em um servidor de produção usando discourse_theme para depuração.

Estou colocando isso em um 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"
        // );
...

E parece que a função não é chamada para carregar o script se eu não chamar this.ensureQRCode();, o que você não parece estar fazendo em seu componente.

O script está disponível e eu posso recuperá-lo (então eu acertei as coisas em about.json e /assets/qrcode.js), mas o navegador se recusa a carregá-lo.

2 curtidas

O resultado do seu loadscript é uma promessa, então você precisa colocar seu código que depende dela em um bloco .then, conforme meu exemplo de código.

3 curtidas

Não sei se isso é algo parecido (suspeito que não), mas isso está me deixando louco porque deveria ser simples de fazer.

1 curtida

Muito obrigado!

Mas pensei que já tinha feito isso:

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

Tentei mudar o mínimo possível do seu exemplo :slight_smile:

Talvez eu precise usar um .then quando estiver tentando usar o código mais tarde?

Mas isso não resolve o problema de CSP, resolve?

image

2 curtidas

Meus dois principais conselhos são:

Coloque a biblioteca na pasta de assets

Isso resolve o CSP, torna o tema autônomo e é considerado uma boa prática, em vez de carregá-lo de terceiros.

Carregue-o preguiçosamente

Somente quando necessário, você pode carregá-lo preguiçosamente usando await loadScript. Isso significa que ele não será carregado em páginas onde não é necessário, diminuindo a velocidade de todo o seu site.


Um bom exemplo de um tema que segue essas boas práticas é GitHub - discourse/discourse-mermaid-theme-component

6 curtidas

Sim, precisamente. :+1:. É assim que funciona no meu exemplo.

3 curtidas

Mais uma pergunta: Qual a diferença entre ...initializers/mycode.js e ...api-initializers/mycode.js?

E muito obrigado a ambos!!

Esse foi um bom exemplo! Consegui entender!

Bem, eu pensei que tinha seguido seu exemplo. Javascript ainda parece um labirinto sinuoso de passagens que se parecem todas iguais.

3 curtidas