테마 컴포넌트에 라이브러리를 불러오는 방법

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

@merefield – 이게 여전히 이렇게 하는 방법인가요?

브라우저에서 QR코드를 생성하기 위해 qrcode.js 를 가져오려고 하고 있습니다.

CSP에도 막히고 있습니다. 같은 호스트에 있는 것이면 왜 CSP 문제인지 이해가 되지 않습니다. discourse_theme를 사용하여 디버깅 중인 프로덕션 서버에서 발생하는 문제입니다.

초기화자(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"
        // );
...

그리고 this.ensureQRCode();를 호출하지 않으면 스크립트를 로드하는 함수가 호출되지 않는 것 같습니다. 하지만 컴포넌트에서는 이를 수행하지 않는 것으로 보입니다.

스크립트는 사용 가능하며 가져올 수 있습니다(즉, about.json과 /assets/qrcode.js의 설정이 맞다는 뜻입니다) 하지만 브라우저가 로드하기를 거부합니다.

loadscript의 결과가 Promise이므로, 예제 코드처럼 해당 결과를 사용하는 코드를 .then 블록에 배치해야 합니다.

이게 비슷한 문제인지 모르겠어요 (아니라고 의심하지만요). 그런데 이건 정말 단순하게 처리할 수 있는 건데, 너무 짜증나서 미칠 것 같아요.

정말 감사합니다!

하지만 저는 이미 그렇게 했다고 생각했는데:

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

예시를 가능한 한 최소한으로만 수정하려고 많이 노력했습니다. :slight_smile:

나중에 코드를 사용할 때 .then을 사용해야 하는 건가요?

하지만 그렇게 해도 CSP 문제를 해결하는 건 아니죠?

image

두 가지 주요 조언은 다음과 같습니다:

라이브러리를 assets 폴더에 배치하세요

이렇게 하면 CSP 문제를 해결하고, 테마를 자체적으로 완결되게 만들며, 서드파티에서 로드하는 것보다 좋은 관행으로 간주됩니다.

지연 로드(Lazy Load)를 사용하세요

필요할 때만 await loadScript를 사용하여 지연 로드할 수 있습니다. 이는 필요하지 않은 페이지에서 로드되지 않도록 하여 사이트 전체의 성능 저하를 방지합니다.


이러한 좋은 관행을 따르는 테마의 좋은 예시는 GitHub - discourse/discourse-mermaid-theme-component · GitHub 입니다.

네, 정확합니다. :+1: 제 예제에서도 그렇게 작동합니다.

한 가지 더 질문이 있습니다: ...initializers/mycode.js와 ...api-initializers/mycode.js의 차이점은 무엇인가요?

두 분 모두에게 큰 감사를 드립니다!!

정말 좋은 예시였습니다! 이해할 수 있었습니다!

음, 저는 당신의 예시를 따랐다고 생각했습니다. 자바스크립트는 여전히 모두 비슷해 보이는 꼬여 있는 미로 같은 통로 같습니다.