Javascript in un componente del tema

Sto cercando di costruire un componente del tema per l’anteprima di file STL. Esiste un’ottima libreria JavaScript per questo scopo, ma non sono sicuro di come farla funzionare all’interno di un componente del tema.

Si tratta di JavaScript standard, non ES6, il che significa che non posso semplicemente inserirlo nella directory “javascripts” e importarlo, giusto? Inoltre, sembra che la libreria dipenda dall’importazione tramite un tag script.

Quindi potrei creare un tag script e aggiungerlo all’intestazione del documento, ma come faccio a trovare il nome del file JS della libreria? Inoltre, la libreria è composta da diversi file JS e presuppone che tali file siano disponibili nella stessa directory. Procede poi a creare tag script aggiuntivi per caricare il resto della libreria.

Quindi, questi file dovrebbero andare nella directory “javascripts”? O dovrebbero essere trattati come asset? La cosa più simile che riesco a trovare per fare qualcosa di analogo è il plugin discourse-math, ma se possibile preferirei mantenere tutto come componente del tema.

Sembra che questo mostri come farlo per un plugin: How to ship javascript library with plugin?
Non ho ancora trovato nulla per un componente del tema.

Non lo so, ma non hai risposte valide!

La prossima cosa da esaminare è la… cosa… relativa all’inclusione di altri file nel componente del tema.

Penso che alcuni dei principali componenti del tema siano il punto di partenza. Fondamentalmente, credo che la struttura dei file del componente del tema sia la stessa e che Ember carichi semplicemente quei file del tema allo stesso modo di un plugin.

Non credo, ogni componente ha la propria directory virtuale, credo. Qualcosa come discourse/theme-10/… Quindi, per caricare contenuti da lì, devo almeno sapere in qualche modo qual è la directory.

1 Mi Piace

I nomi delle risorse sembrano essere accessibili solo come variabili, e i nomi reali sono lunghi numeri complicati, quindi nemmeno questo funzionerà.
Sembra quasi che al momento non ci sia un modo per farlo come componente, quindi per ora caricherò i file JS tramite nginx e vi accederò in questo modo. Probabilmente significa che, purtroppo, questo componente funzionerà solo per me.

Puoi aggiungere il tag script normale al file header.html all’interno del componente del tuo tema.

Il sideloading funziona!
Una volta sola. :frowning:

Se navigo verso un altro argomento e poi torno a quello contenente l’STL, non funziona più. Non sono sicuro del motivo, poiché nella console di JavaScript non compare alcun errore. Ho visto da qualche parte in precedenza un thread che parlava di stranezze legate all’onload e, dato che questi script utilizzano onload, potrebbe essere correlato?

Vero, ma il codice viewstl non è destinato a essere incorporato.
Con il sideloading ho inserito un tag script come questo in common/head_tag.html:

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

(/xi/ è servito da nginx)

Discourse è una SPA. Non puoi semplicemente aggiungere uno script con onLoad, poiché non funzionerà. Dovrai collegarti ai nostri endpoint API. Consulta la Guida per gli sviluppatori sui temi di Discourse.

Va bene allora, ci provo a sostituire il caricamento basato su script tag datato con qualcosa di diverso.

Ho letto questa pagina diverse volte, ma non riesco ancora a farla funzionare.
Sto cercando di caricare three.js con le istruzioni import, ma sembra che, indipendentemente da ciò che faccio, lamenti di non riuscire a trovare l’import. La parte strana è che riesco a importare altri file senza problemi, e il messaggio di errore è completamente inutile.

Comunque, ecco cosa ottengo, forse qualcuno può aiutare:

Ecco l’import che non funziona:

E questo è l’errore che ricevo:

_application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333 Si è verificato un errore nel tema/componente "STL previews": Errore: Impossibile trovare il modulo `discourse/theme-17/three/build/three.module` importato da `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

Il ‘.’ è un separatore di modulo magico o qualcosa del genere?

Immagino che ‘.’ sia magico, perché quando rinomino three.module.js in three_module.js, ottengo un problema completamente diverso: non riesco più a caricare il tema. (Errore 500)

Ho anche provato a importare three.js direttamente da un CDN con un URL completo, ma sembra che non funzioni nemmeno…

Se hai solo bisogno del caricamento Just In Time di una risorsa JavaScript, come nel mio caso dove richiedo la libreria D3, puoi utilizzare questo pattern con Loadscript:

e poco sopra:

Loadscript restituisce una Promise, quindi devi eseguire un .then sul risultato. (Non ne sono certo, ma suppongo che il risultato sia memorizzato nella cache in modo implicito, quindi verrà eseguito più velocemente la seconda volta, ecc.)

Come puoi vedere, puoi concatenarli per caricare più script uno dopo l’altro.

Nota che viene eseguito all’interno di un componente Ember e viene attivato dal hook didInsertElement. Per saperne di più sui componenti Ember, visita: Templates are HTML - Components - Ember Guides

Nota anche che gli script stessi sono ospitati nella directory javascripts/assets.

Ho basato questo sul codice di @j.jaffeux utilizzato da qualche parte per caricare uno script completamente diverso (grazie Joffrey! :+1: )

Ecco un esempio Discourse:

Consiglio: esplora sempre i TC Ufficiali e Pavilion e i plugin che fanno qualcosa di simile per vedere come realizzano le cose :).

4 Mi Piace

Interessante, grazie per i suggerimenti.
Proverò a usare loadScript e vedrò se può risolvere il mio problema.

2 Mi Piace

Ho deciso di provare un approccio più semplice.
Ho creato un iframe che carica una pagina HTML in grado di eseguire tutte le operazioni di scripting più complesse per far funzionare l’anteprima. Al momento non è in un formato riutilizzabile, ma sarebbe relativamente semplice creare un plugin per essa.