Na próxima semana, vou mesclar este PR que permite que temas e componentes tenham testes QUnit, mas também altera a forma como o JavaScript dos temas é processado/transpilado pelo Discourse. Fazer essas alterações de maneira compatível com versões anteriores é muito difícil sem reescrever grande parte do código principal (o que pode, inclusive, introduzir outras incompatibilidades), então as alterações podem quebrar o JavaScript dos seus temas/componentes ao atualizar seu site.
Neste post, vou explicar quais são as alterações que podem afetar seus temas/componentes e o que você precisa fazer para corrigi-los.
1. JavaScript dentro de tags <script type="text/discourse-plugin"> será invocado com o modo estrito ativado
Essa alteração não afeta código JS que não esteja dentro de tags <script type="text/discourse-plugin">. Você está completamente seguro dessa alteração se seu código estiver em tags <script> regulares ou em arquivos .js independentes.
A maneira mais fácil de saber se seu tema/componente é afetado por essa alteração é envolver seu código JS em uma Expressão de Função Imediatamente Invocada (IIFE) e adicionar "use strict"; no topo do seu código. Por exemplo, digamos que seu código de tema atualmente se pareça com isso:
<script type="text/discourse-plugin" version="0.8.11">
a = 5;
console.log(a);
</script>
Após envolvê-lo em uma IIFE, ele deve ficar assim ("use strict"; é importante porque ativa o modo estrito e queremos testar como nosso código se comporta nesse modo):
<script type="text/discourse-plugin" version="0.8.11">
(function() {
"use strict";
a = 5;
console.log(a);
})();
</script>
Se seu componente parar de funcionar após fazer isso, ele quebrará ao atualizar seu site. Para corrigir seu código, recomendo fortemente que você primeiro leia a documentação do MDN sobre o modo estrito do JavaScript e verifique se seu tema/componente faz algo proibido no modo estrito. Se fizer, você precisará refatorar seu código para que não faça nada proibido.
O erro mais provável que você verá é ReferenceError ao declarar uma variável sem a palavra-chave var (ou let/const). No exemplo acima, a linha a = 5; lançará uma exceção ReferenceError no modo estrito porque esquecemos de adicionar var. O código ficará assim após corrigi-lo:
<script type="text/discourse-plugin" version="0.8.11">
(function() {
"use strict";
var a = 5;
console.log(a);
})();
</script>
Quando terminar de testar/corrigir seu código, sinta-se à vontade para remover a IIFE e a linha "use strict";.
2. Os caminhos dos módulos JavaScript dos temas serão prefixados com os IDs dos temas.
Há algum tempo, adicionamos um novo recurso que permitiu que o JavaScript dos temas fosse dividido em vários arquivos, e preciso dar um pouco de contexto sobre como esse recurso funciona para explicar a mudança que está por vir.
Quando um tema/componente que vem com arquivos JavaScript independentes é instalado em uma instância do Discourse, o Discourse percorre todos os arquivos JavaScript e cria um módulo JavaScript para cada um. Cada módulo precisa ter um identificador único (também conhecido como caminho), então o Discourse usa o caminho do arquivo (com pequenas alterações) como o caminho do módulo.
Por exemplo, se seu tema/componente tiver um arquivo em javascripts/discourse/helpers/my-helper.js, o Discourse criará um módulo para esse arquivo e atribuirá discourse/helpers/my-helper como seu caminho, e o módulo conterá uma versão transpilada do JavaScript dentro do arquivo original.
A vantagem dos módulos é que você pode importar classes/funções/objetos etc. de um módulo para outro. Por exemplo, você pode importar uma função chamada xyz de my-helper para outros módulos usando uma instrução import assim:
// javascripts/discourse/controllers/my-theme-controller.js
import { xyz } from "discourse/helpers/my-helper";
O PR que vou mesclar na próxima semana adicionará um prefixo aos caminhos dos módulos dos temas. Então, em nosso exemplo, my-helper mudará de discourse/helpers/my-helper para discourse/theme-<theme_id>/helpers/my-helper. Isso significa que nossa instrução import deixará de funcionar porque o caminho do módulo terá mudado. Para corrigir, precisamos apenas alterar o caminho na instrução import de absoluto para relativo, assim:
// javascripts/discourse/controllers/my-theme-controller.js
import { xyz } from "../helpers/my-helper";
Agora nossa instrução import deve funcionar novamente. Veja esses PRs 1 e 2 para exemplos reais de componentes afetados pela alteração (2) e como foram corrigidos.
Novamente, isso só afeta seu tema/componente se ele importar de um de seus próprios módulos; importar módulos principais não é afetado por essa alteração.
Espero que isso ajude. Se tiver alguma dúvida, por favor, me avise!