テーマコンポーネント内のJavascriptアセット

STL プレビュー用テーマコンポーネントの構築を試みています。これには 優れた JavaScript ライブラリ がありますが、テーマコンポーネント内でどのように動作させるべきか確信が持てません。

これは ES6 ではなく通常の JavaScript のため、単に「javascripts」ディレクトリに置いてインポートすることはできないと思います。加えて、このライブラリはスクリプトタグからのインポートを前提としているようです。

したがって、スクリプトタグを作成してドキュメントの <head> に追加することはできますが、ライブラリの JS ファイル名をどう特定すればよいのでしょうか?また、このライブラリは複数の JS ファイルで構成されており、それらのファイルが同じディレクトリにあることを前提としています。さらに、ライブラリの残部を読み込むために追加のスクリプトタグを生成します。

では、これらのファイルは「javascripts」ディレクトリに入れるべきでしょうか、それともアセットとして扱うべきでしょうか?似たような処理の例として discourse-math プラグインが見つかりますが、可能であればこれをテーマコンポーネントのままにしたいと考えています。

これは プラグイン での実装方法を示しているようです:How to ship javascript library with plugin?
テーマコンポーネントに関する情報はまだ見つかっていません。

わかりませんが、良い答えを持っていないのはあなたの方です!

次に確認すべきは、テーマコンポーネント内で他のファイルを含めることに関する…あの…点です。

おそらく、主要なテーマコンポーネメントを確認すればよいでしょう。基本的には、テーマコンポーネントのファイル構造は同じであり、Ember はプラグインと同じようにそれらのテーマファイルを読み込むと考えています。

おそらく、各コンポーネントはそれぞれ独自の仮想ディレクトリを持っていると思います。discourse/theme-10/… のような感じです。そのため、そこから何かを読み込むには、少なくともそのディレクトリが何であるかを何らかの方法で知る必要があります。

「いいね!」 1

アセット名は変数としてのみアクセス可能で、実際の名称は長く複雑な数字であるため、この方法も機能しません。
現時点では、これをコンポーネントとして実装する方法がないように思えるため、当面は nginx を介して JS ファイルをサイドロードし、その方法でアクセスすることにします。残念ながら、このコンポーネントは私自身のみで機能することになるかもしれません。

テーマコンポーネント内の header.html ファイルに、通常の script タグを追加できます。

サイドローディングは機能します!
1回だけですが。:frowning:

別のトピックに移動し、STL が含まれるトピックに戻ると、機能しなくなります。JavaScript コンソールにエラーが表示されないため、理由がわかりません。以前どこかで、onload の奇妙な動作について議論されたスレッドを見たのですが、これらのスクリプトが onload を使用していることを考えると、関連があるかもしれませんね?

その通りですが、viewstl のコードはインライン化することを想定していません。
サイドローディングでは、common/head_tag.html に以下のような script タグを配置しています:

<script src="/xi/viewstl/stl_viewer.min.js"></script>

(/xi/ は nginx から提供されています)

Discourse は SPA(シングルページアプリケーション)です。単に onLoad でスクリプトを追加するだけでは動作しません。当社の API エンドポイントにフックする必要があります。Discourse テーマのデベロッパーガイド をご確認ください。

よし、古いスクリプトタグベースの読み込みを別の方法に置き換えてみようと思います。

このページを何度か読みましたが、まだ動作させることができません。
import 文を使って three.js を読み込もうとしているのですが、何をしても「import が見つからない」というエラーが出てしまいます。奇妙なことに、他のファイルの import は問題なく動作するのです。さらに、エラーメッセージも全く役に立ちません。

とりあえず、私が得たエラー内容を以下に示します。何か助けになる方がいれば幸いです:

動作しない import 文はこちら:

そして、表示されるエラーはこちらです:

_application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333 "STL previews" テーマ/コンポーネントでエラーが発生しました: Error: Could not find module `discourse/theme-17/three/build/three.module` imported from `discourse/theme-17/stlviewer/StlViewer`
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74612)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74616)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
(anonymous) @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333
u @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74325
initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74304
i.initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:7723
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49335
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67724
e.walk @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67638
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67568
e.topsort @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67576
_runInitializer @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49361
runInitializers @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49333
_bootSync @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47768
domReady @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47668
n._run @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67275
n._join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67251
n.join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:66968
f @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53760
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53864
l @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3776
c @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3844
setTimeout (async)
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3882
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
fire @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3648
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
ready @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4120
z @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4130

「.」は何か特別なモジュール区切り文字なのでしょうか?

「.」は魔法の文字のようです。three.module.js を three_module.js にリネームすると、全く別の問題が発生します。テーマが読み込めなくなります(500 エラー)。

CDNからフルURLでthree.jsを直接インポートしようとしましたが、それもうまくいかないようです…。

JavaScript アセットのジャストインタイム読み込みが必要な場合(ここでは D3 ライブラリを読み込む必要がある場合など)、Loadscript を使ったこのパターンを利用できます:

さらに上の方では:

LoadscriptPromise を返すため、結果に対して .then を実行する必要があります。(確信はありませんが、結果は暗黙的にキャッシュされるため、2 回目以降はより高速に実行されると想定しています。)

ご覧の通り、これらを連結して複数のスクリプトを順番に読み込むことができます。

これは Ember コンポーネント内で実行されており、didInsertElement フックから発火しています。Ember コンポーネントについて詳しくはこちらをご覧ください:Templates are HTML - Components - Ember Guides

また、スクリプト自体は javacsripts/assets ディレクトリに格納されている点にもご注意ください。

これは、@j.jaffeux さんが全く異なるスクリプトを読み込むために使用したコードを基にしています(ありがとう Joffrey! :+1:

以下は Discourse の例です:

ヒント:同様の処理を行っている公式 TC や Pavilion TC、プラグインを掘り下げて、どのように実現しているかを確認するのがおすすめです :slight_smile:

「いいね!」 4

興味深いですね、ご指摘ありがとうございます。
loadScript を使ってみて、それが私の問題を解決できるか試してみます。

「いいね!」 2

よりシンプルなアプローチを試すことにしました。
HTML ページを読み込む iframe を作成し、プレビューを動作させるための厄介なスクリプト処理をそのページで行うようにしています。現在は再利用可能な形式ではありませんが、プラグインとして作成するのは比較的簡単でしょう。