テーマコンポーネントからJSアセットをロードする際の問題

こんにちは。Discourseでの開発は初めてなので、初歩的な質問かもしれませんがご容赦ください。
PGN(チェス盤と対局)を表示するテーマコンポーネントを構築しています。
理論的にはそれほど難しくなく、PGNViewer.jsというJavaScriptコンポーネントがあり、[wrap]タグを適切な\u003cscript\u003evar x='pgn here'; ...\u003c/script\u003eおよび\u003cdiv class='pgn-blahblah'\u003e\u003c/div\u003eブロックに変換できました。
ここまでは順調ですが、次にJavaScriptをロードする必要があります。
import loadScript from \"discourse/lib/load-script\";およびawait loadScript(settings.theme_uploads_local.pgnviewer_js);を使用して、初期化時に/assets/ディレクトリからロードできることがわかりました。
しかし、ここでいくつか問題があります。
開発環境ではコンポーネントをロードできますが、本番サーバーではアセットが大きすぎるというエラーが表示され、ロードできません。この問題を解決する方法はありますか?
次に、開発環境では/theme-javascripts/dist.js.mapをロードできなかったという警告が表示されます。どこから来ているのか全くわかりません。何か提供する必要があるものはありますか?
全体として、このアプローチは正しいのでしょうか、それともプラグインを実装する方が良いでしょうか?
よろしくお願いします。

FF

「いいね!」 2

Metaへようこそ、@happycactus :wave:

はい、おそらく。プラグインが必要になるのは、API(つまりバックエンド)を変更しようとしている場合だけです。

過去に同様の問題がありました。

はい、app.ymlを変更して、リバースプロキシ(nginx)で大きなファイルを処理できるようにする必要があります。

幸いなことに、これは簡単な設定です。upload_size:、ここではコンテキストで示します。

params:
  ## このコンテナはどのGitリビジョンを使用する必要がありますか? (デフォルト: tests-passed)
  version: tests-passed

  ## 最大アップロードサイズ (デフォルト: 10m)
  upload_size: 20m

これを変更したら、効果を発揮するために再構築する必要があります。

./launcher rebuild app

もちろん、これはサーバーへの適切なアクセス権があることを前提としています…

「いいね!」 2

ロバートさん、ありがとうございます!

dúvida, provavelmente porque não tenho experiência com tais plataformas.
Minha dúvida é:

minha abordagem é “incorporar” o pequeno trecho de JavaScript necessário para preencher o bloco div com o conteúdo, mas vejo que talvez eu possa executá-lo a partir de uma função “cookPgn”, como é feito no componente marmaid:

async function applyMermaid(element, key = "composer") {
  const mermaids = element.querySelectorAll("pre[data-code-wrap=mermaid]");
  ...
  await loadScript(settings.theme_uploads_local.mermaid_js);
  ...
  mermaids.forEach((mermaid) => {
    if (mermaid.dataset.processed) {
      return;
    }

    const spinner = document.createElement("div");
    spinner.classList.add("spinner");
    ...
    mermaid.append(spinner);
  });

Dessa forma, se entendi corretamente, não preciso carregar o script da página (usando loadScript, talvez??), mas posso simplesmente importá-lo no js do tema? Ou provavelmente estou totalmente enganado!
Quero dizer, qual é a diferença entre loadScript e um simples import?
Você pode me indicar algum recurso da web onde eu possa entender melhor isso?
Desculpe novamente se as perguntas são triviais ou estúpidas!

Outra coisa, o limite é por padrão de 10M, mas meu ativo é de cerca de 300kb, e todo o zip é de 337kb, ainda assim durante o upload ele diz que é mais de 512kb.

Obrigado,

FF

import を試しましたか?外部スクリプトを import することはできないと思います。

Loadscript が正しいアプローチであり、コードがそれを処理して使用する前にスクリプトが完全にロードされることを保証します(これが Promise を返す理由です)。

正確なエラーを共有していただけますか?ブラウザのコンソールに表示されていますか?

あなたの実際の問題は、CSPによって禁止されているインラインJSを使用しようとしていることです。

このコードをテーマコンポーネントコードのヘルパー関数に入れ、投稿内に挿入しないでください。

現在のテーマをGitHubにアップロードしていただければ、確認することもできます。

「いいね!」 5

Discourse Mermaid コンポーネントを確認してください。これはライブラリをロードし、投稿に何らかの処理を行います。

「いいね!」 2

ありがとうございます、@Falcoさん。それが私の疑問の一つでした。

はい、こちらです: GitHub - studiofuga/discourse-pgn-component: A theme component for Discourse to display PGN blocks
プラグイン版もありますが、このアプローチは取らず、テーマコンポーネントのままでいこうと思います。

@pfaffmanさん、ありがとうございます。実際、そこからインスピレーションを得ました。そして、上記で提案されたようにコードを注入することなく、まさに私が求めていることを正しく行っていることに気づきました。

皆さん、ありがとうございます。提案された方法を試して、結果を報告します。もちろん、私のコードはオープンソースなので、どのような貢献や批判でも大歓迎です。

「いいね!」 1

私のミスでした。添付ファイルのサイズを512kBに制限していたことを忘れ、デフォルト(4096)に引き上げたところ、うまく機能しました。ありがとうございます。そして、くだらない質問をして申し訳ありませんでした。

「いいね!」 2

すべて修正してコンポーネントが動作するようになりました!しかし、問題が発生しました。使用しているライブラリで「unsafe eval」が発生しています。おそらく、アップストリームライブラリを修正する必要があるでしょう。パッケージ化の方法がわかりません。
興味のある方のために、すべての変更を上記の私のリポジトリにプッシュしました。エラーの詳細は以下の通りです。

そして、元のjsモジュールでの該当行はこちらです。

let isBrowser=new Function("try {return this===window;}catch(e){ return false;}")

こちらです。

「いいね!」 1

本番環境でコンテンツセキュリティポリシーによりスクリプトがエラーを起こしています。

サイト設定の content security policy script src'unsafe-eval' を追加する必要があります。

ありがとうございます。これを実行する方法を調べるためにドキュメントを閲覧しています。 :slight_smile: たくさん学んでいます、ありがとうございます。

「いいね!」 1

わかりました、できました。’ を使う必要がありましたが…(笑)。とにかく、私のスクリプトはほぼ機能しました。すべてをメインにプッシュしたところ、なぜか機能しました。レンダリングに問題があるようですが、少なくともメインコンポーネントは呼び出されています(問題はそこにあると疑っています)。
皆さん、ありがとうございました…またすぐに質問しに来ます(笑)。ありがとう!

「いいね!」 1

unsafe-eval を CSP に追加することは、CSP の目的をほぼ無効にし、結果としてサイトのセキュリティを低下させることを念頭に置いてください。

eval の使用はコードの臭いであり、上記で指摘したように、アップストリームで修正する必要があります。

「いいね!」 4

はい、もちろんです。現時点では修正できませんが、まずはコンポーネントを修正し、次にアップストリームライブラリを修正してCSPオーバーライドを削除する予定です。
アドバイスありがとうございます!

ほぼ完了しました。「something」を表示できましたが、ランダムに動作しています。
使用しているJSライブラリは次のように動作します。

まず、一意のIDを持つ<div id='board'>ブロックを定義する必要があります。次に、divを埋める関数を起動する必要があります。たとえば、PGNV.pgnBoard('board', {}); のようなものです。スクリプトは、それを埋めるために同じIDを必要とします。

私の理解が正しければ、調理済みブロックを装飾している間はこれを実行できません。ドキュメントがまだ埋められておらず、PGNVオブジェクトがブロックを見つけられないためです。そのため、最初にウィジェットを使用しました(HTML関数はブロックを返す必要があり、それを持っていないため機能しませんでした)。次に、デバウンス関数に切り替えました:debounceFunction(this, renderPgn, attrs, 200);

しかし、それは「時々」機能します。

何が足りないのでしょうか?

ありがとうございます。

debounceFunction は、デバウンス期間中に追加のデバウンス呼び出しがない場合にのみ、ターゲットメソッドの呼び出しを遅延させます。それでも機能しない場合があるのは、

debounce は、あなたのユースケースの解決策ではない可能性があります。

afterAdopt オプションを試してみてください。

「いいね!」 1

こんにちは、Hawnさん、ヒントをありがとうございます!
まさに探していたものだと思います。2つの異なるアプローチを試しました。

  • まず、通常の「decorateCooked」を使用してdivブロックを解析してアタッチし、次にafterAdoptで PGNV.pgnviewer() を呼び出してレンダリングします。または
  • afterAdoptオプションのみを使用して、アタッチとレンダリングの両方を行います。

どちらもまだ別の問題で機能しませんでした。完全に理解できませんが、内部ライブラリがDOM要素で className 属性が見つからないというエラーでクラッシュしているようです。少し途方に暮れています :slight_smile: 。誰かがloadScriptを使用しているのを見ましたが、私はライブラリをインポートしただけで、debounce関数を使用したらうまくいきました。両者の違いは何ですか?

ありがとうございます!

こんにちは @hawm さん、原因が見つかりましたが、行き詰まっています。
もちろん、私はEmberも最近のJavaScriptも全くの初心者です。そこで少し勉強して、理由を突き止めました。
PgnViewerJsは、Virtual DOMではなく、実際のDOMで動作することを期待しています。そのため、調理された要素が採用された後でも、実際のDOMには存在せず、PGNVはdocument.getElementByIdを使用してIDを検索します。
見つけられる限りのことをすべて調べました。Emberコンポーネントは私のニーズに合っているようですが、それをどのように処理すべきか確信が持てません。
あるいは、API.onAppEventでしょうか?

よろしくお願いします。

Emberのlater()を使用しました。これはダーティハックですが、機能します。
何かより良い解決策はありますか?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.