Как установить пакеты npm в пользовательских темах/плагинах

Привет!

Возможно ли установить пакеты npm (через package.json или аналогичный способ) в темах/плагинах Discourse? Мы хотим переиспользовать некоторые компоненты между приложениями, и если это невозможно, это может стать препятствием.

Спасибо!

Вы можете примерно сделать то, что мы делаем в ядре: добавлять пакеты npm через package.json, а затем копировать JS-файлы в папку темы (например, javascripts/discourse/lib/). Однако, я не думаю, что будет работать прямой импорт пакетов из node_modules.

Предположим, у нас есть обычный JavaScript-код (например, такой, который можно подключить и запустить для поддержки пользовательского веб-компонента) как этот. Как я могу запустить его с помощью вашего подхода? Когда я копирую и вставляю его в discourse/lib в рамках моей темы, он не работает.

Я предполагаю, что это не работает, потому что код «вызывается не в нужное время», то есть он не вызывается при загрузке страницы и в среде браузера.

Кроме того, для контекста: если я попробую использовать https://unpkg.com/ и включу его в заголовок, я получу ошибку, например:

После ответа на комментарий и передачи информации в виде единой идеи я устранил ошибку, следуя инструкции по адресу DISCOURSE_CDN_URL causes content security policy violations?

Отключив настройку content_security_policy

Я всё ещё пытаюсь понять, почему скрипт не работает, так как у меня есть другая ошибка, но, возможно, это уже полезно для кого-то другого.

К сведению, вот ошибка, с которой я столкнулся:

Но скрипт загрузился :man_shrugging:

Наконец, для кого-то в рамках одного квеста. Я заставляю это работать так:

  1. Отключаю настройку content_security_policy.
  2. Явно добавляю скрипт программно (не используя $.getScript и не используя другие подходы).

Пример краткого фрагмента того, что работает у меня (замените web-component на то, что имеет смысл в вашем случае):

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"
          },
          `Hello world`
        );

        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);
}

Более правильный способ сделать это — добавить этот конкретный URL в белый список либо в настройке сайта content security policy script src, либо в компоненте вашей темы. Подробнее см. Смягчение атак XSS с помощью политики безопасности контента.

Кроме того, вы можете выполнить import loadScript from "discourse/lib/load-script"; и использовать этот метод для загрузки внешнего скрипта (вместо того чтобы определять собственный инжектор addScript).

Извините за воскрешение этой темы, но это наиболее релевантная из тех, что я смог найти.
Я пытаюсь добавить этот пакет в плагин. Я хотел бы импортировать его так: import { RadixDappToolkit, RadixNetwork } from '@radixdlt/radix-dapp-toolkit'.

Он также доступен в Yarn, который, как я полагаю, используется в Discourse, но я не думаю, что могу просто добавить его как зависимость… так ли это?

Я также не уверен, что могу загрузить его через unpkg, так как у него много зависимостей. Какие у меня есть варианты? Буду признателен за любые подсказки.

Извините за общий вопрос, но я очень запутался. Спасибо!