カスタムテーマやプラグインでの npm パッケージのインストール方法

こんにちは!

Discourse のテーマやプラグインで npm パッケージ(package.json などを通じて)をインストールすることは可能でしょうか?複数のアプリ間で一部のコンポーネントを再利用したいと考えており、これができない場合は大きな障壁となります。

よろしくお願いいたします!

コアでやっていることを少し模倣して、package.json を介して npm パッケージを追加し、その後 JS ファイルをテーマフォルダ(例えば javascripts/discourse/lib/ など)にコピーするという方法があります。ただし、node_modules から直接パッケージをインポートすることはできないと思います。その方法は動作しないでしょう。

通常の JavaScript コード(カスタム Web コンポーネントをサポートするために含めて実行できるようなもの)があると仮定しますこちらのようなもの。これをあなたのアプローチで実行するにはどうすればよいでしょうか?テーマ内の discourse/lib にコピーして貼り付けると、動作しません。

動作しない理由は、「適切なタイミングで呼び出されていないからではないか」と考えられます。つまり、ページが読み込まれた際やブラウザ環境内での呼び出しがなされていないためではないでしょうか。

さらに、皆様の参考までに、https://unpkg.com/ を使用してヘッダーに含めようとすると、以下のようなエラーが発生します:

コメントに返信し、単一のアイデアとして情報を伝えることで、DISCOURSE_CDN_URL causes content security policy violations? に従ってエラーを解消しました。

content_security_policy 設定を無効にする

スクリプトがなぜ動作しないのか(別のエラーが発生しているため)は依然として不明ですが、少なくとも他の誰かの参考にはなるかもしれません。

参考までに、私が遭遇しているエラーは以下の通りです:

ただし、スクリプトは読み込まれています🤷‍♂️

最後に、同じクエスト内の誰かのために。私は以下のように動作させています:

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

これを行うより良い方法は、content security policy script src サイト設定またはテーマコンポーネントで、その特定の URL をホワイトリストに登録することです。詳細については、Mitigate XSS Attacks with Content Security Policy を参照してください。

また、import loadScript from "discourse/lib/load-script"; をインポートして、外部スクリプトを読み込むために使用することもできます(独自の addScript インジェクタを定義する代わりに)。

このスレッドを掘り起こして申し訳ありませんが、見つけられた中で最も関連性の高いものです。
プラグインにこのパッケージを追加しようとしています。import { RadixDappToolkit, RadixNetwork } from '@radixdlt/radix-dapp-toolkit'を使用してインポートしたいと思います。

Yarnでも利用可能ですが、Discourseはそれを使用していると思います。しかし、依存関係として追加するだけではだめだと思いますか?

多くの依存関係があるため、unpkgを使用してロードすることもできないと思います。どのような選択肢がありますか?何かヒントがあれば幸いです。

質問が広範で申し訳ありませんが、非常に混乱しています。ありがとうございます!