Javascript assets em um componente de tema

Estou tentando criar um componente de tema para pré-visualização de STL. Existe uma excelente biblioteca JavaScript para isso, mas não tenho certeza de como fazê-la funcionar dentro de um componente de tema.

É JavaScript regular, não ES6, o que, creio eu, significa que não posso simplesmente colocá-la no diretório “javascripts” e importá-la, certo? Além disso, a biblioteca parece depender de ser importada a partir de uma tag script.

Então, posso criar uma tag script e adicioná-la ao cabeçalho do documento, mas como descubro o nome do arquivo JS da biblioteca? Além disso, a biblioteca é composta por vários arquivos JS e pressupõe que esses arquivos estarão disponíveis no mesmo diretório. Ela, por sua vez, cria tags script adicionais para carregar o restante da biblioteca.

Portanto, esses arquivos devem ir para o diretório “javascripts”? Ou devem ser tratados como ativos? A coisa mais próxima que consigo encontrar para fazer algo similar é o plugin discourse-math, mas, se possível, prefiro manter isso como um componente de tema.

Isso parece mostrar como fazer para um plugin: How to ship javascript library with plugin?
Ainda não encontrei nada para um componente de tema.

Não sei, mas você não tem boas respostas!

A próxima coisa a verificar é… aquela coisa… sobre incluir outros arquivos no componente do tema.

Acho que alguns dos principais componentes de tema são onde procurar. Basicamente, acho que a estrutura de arquivos do componente do tema é a mesma e o Ember simplesmente carrega esses arquivos de tema da mesma forma que um plugin.

Não acho que seja assim. Acredito que cada componente tenha seu próprio diretório virtual. Algo como discourse/theme-10/… Então, para carregar coisas de lá, preciso pelo menos saber qual é o diretório de alguma forma.

1 curtida

Os nomes dos ativos parecem ser acessíveis apenas como variáveis, e os nomes reais são números longos e complicados, então isso também não funcionará.
Parece que não há como fazer isso como um componente no momento, então vou fazer o carregamento lateral dos arquivos JS por meio do nginx e acessá-los dessa forma por enquanto. Provavelmente significa que, infelizmente, este componente só funcionará para mim.

Você pode adicionar a tag script normal ao arquivo header.html dentro do componente do seu tema.

O sideloading funciona!
Uma vez. :frowning:

Se eu navegar para outro tópico e voltar ao tópico que contém o STL, ele não funciona mais. Não tenho certeza do motivo, pois não há erro no console do JavaScript. Vi um tópico em algum lugar antes que falava sobre estranhezas com o onload e, como esses scripts usam onload, talvez esteja relacionado?

Verdade, mas o código viewstl não foi feito para ser inline.
Com o sideloading, coloquei uma tag script assim em common/head_tag.html:

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

(/xi/ é servido pelo nginx)

O Discourse é uma SPA. Você não pode simplesmente adicionar um script que rode no onLoad, pois isso não funcionará. Você precisará integrar-se aos nossos endpoints da API. Consulte o Guia do desenvolvedor para Temas do Discourse

Tudo bem, então vou tentar substituir o carregamento baseado em script-tag, que já está bem velho, por outra coisa.

Agora li esta página várias vezes, mas ainda não consigo fazer funcionar.
Estou tentando carregar o three.js com instruções de importação, mas parece que, independentemente do que eu faça, ele reclama que não consegue encontrar a importação. A parte estranha é que consigo importar outros arquivos sem problemas, e a mensagem de erro é totalmente inútil.

De qualquer forma, aqui está o que recebo, talvez alguém possa ajudar:

Aqui está a importação que não funciona:

E aqui está o erro que recebo:

_application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333 Ocorreu um erro no tema/componente "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

O ‘.’ é algum separador mágico de módulo ou algo assim?

Acho que o ‘.’ é mágico, porque quando renomeio three.module.js para three_module.js, obtenho um problema completamente diferente: não consigo mais carregar o tema. (Erro 500)

Também tentei importar o three.js diretamente de um CDN com uma URL completa, mas isso também não parece funcionar…

Se você apenas precisa de carregamento Just In Time de um ativo JavaScript, como faço aqui onde preciso da biblioteca D3, você pode usar este padrão com Loadscript:

e um pouco acima:

O Loadscript retorna uma Promise, então você precisa executar um .then no resultado. (Não tenho certeza, mas assumo que o resultado seja armazenado em cache implicitamente, então será mais rápido na segunda vez, etc.)

Como você pode ver, você pode encadeá-los para carregar vários scripts um após o outro.

Note que ele está rodando dentro de um Componente Ember e é acionado pelo hook didInsertElement. Saiba mais sobre Componentes Ember aqui: Templates are HTML - Components - Ember Guides

Note também que os próprios scripts estão armazenados no diretório javascripts/assets.

Baseei isso no código de @j.jaffeux usado em algum lugar para carregar um script completamente diferente (obrigado, Joffrey! :+1: )

Aqui está um exemplo do Discourse:

Dica: sempre procure nos TCs Oficiais e Pavilion e em Plugins que estão fazendo algo semelhante para ver como eles realizam as coisas :).

4 curtidas

Interessante, obrigado pelas dicas.
Vou tentar usar loadScript e ver se isso resolve meu problema.

2 curtidas

Decidi tentar uma abordagem mais simples.
Apenas crio um iframe que carrega uma página HTML capaz de executar todas as tarefas complexas de script necessárias para fazer a pré-visualização funcionar. No momento, não está em um formato reutilizável, mas seria relativamente simples criar um plugin para isso.