Próximos cambios principales que podrían romper algunos temas/componentes (12 de abril)

La próxima semana voy a fusionar esta PR que permite que los temas y componentes tengan pruebas con QUnit, pero también cambia la forma en que Discourse procesa/transpila el JavaScript de los temas. Realizar estos cambios de manera compatible con versiones anteriores es muy difícil sin reescribir gran parte del código principal (lo cual podría introducir otros cambios incompatibles), por lo que es posible que los cambios rompan el JavaScript de tus temas/componentes al actualizar tu sitio.

En este post explicaré cuáles son los cambios que pueden afectar a tus temas/componentes y qué necesitas hacer para solucionarlos.

1. El JavaScript dentro de las etiquetas <script type="text/discourse-plugin"> se ejecutará con el modo estricto habilitado

Este cambio no afecta al código JS que no esté dentro de las etiquetas <script type="text/discourse-plugin">. Si tu código está en etiquetas <script> regulares o en archivos .js independientes, estás completamente seguro ante este cambio.

La forma más sencilla de saber si tu tema o componente se ve afectado por este cambio es envolver tu código JS en una Expresión de Función Invocada Inmediatamente (IIFE) y añadir "use strict"; al principio de tu código. Por ejemplo, supongamos que así es como se ve ahora tu código de tema:

<script type="text/discourse-plugin" version="0.8.11">
  a = 5;
  console.log(a);
</script>

Después de envolverlo en una IIFE debería verse así ("use strict"; es importante porque habilita el modo estricto y queremos probar cómo se comporta nuestro código en este modo):

<script type="text/discourse-plugin" version="0.8.11">
  (function() {
    "use strict";
    a = 5;
    console.log(a);
  })();
</script>

Si tu componente deja de funcionar después de hacer esto, se romperá al actualizar tu sitio. Para solucionar tu código, te recomiendo encarecidamente que primero leas la documentación de MDN sobre el modo estricto de JavaScript y luego verifiques si tu tema o componente realiza alguna acción prohibida bajo este modo. Si es así, necesitas refactorizar tu código para que no realice ninguna acción prohibida.

El error más probable que verás es ReferenceError al declarar una variable sin la palabra clave var (o let/const). En el ejemplo anterior, la línea a = 5; lanzará una excepción ReferenceError en modo estricto porque olvidamos añadir var. El código se ve así después de solucionarlo:

<script type="text/discourse-plugin" version="0.8.11">
  (function() {
    "use strict";
    var a = 5;
    console.log(a);
  })();
</script>

Una vez que termines de probar y corregir tu código, siéntete libre de eliminar la IIFE y la línea "use strict";.

2. Las rutas de los módulos de JavaScript de los temas tendrán un prefijo con los IDs de los temas.

Hace un tiempo añadimos una nueva función que permitía dividir el JavaScript de los temas en múltiples archivos, y necesito dar un poco de contexto sobre esta función para explicar el próximo cambio.

Cuando se instala un tema o componente que incluye archivos JavaScript independientes en una instancia de Discourse, Discourse recorre todos los archivos JavaScript y crea un módulo para cada uno. Cada módulo necesita tener un identificador único (también conocido como ruta), por lo que Discourse utiliza la ruta del archivo (con cambios menores) como la ruta del módulo.

Por ejemplo, si tu tema o componente tiene un archivo en javascripts/discourse/helpers/my-helper.js, Discourse creará un módulo para ese archivo y asignará discourse/helpers/my-helper como su ruta, y el módulo contendrá una versión transpilada del JavaScript dentro del archivo original.

Lo bueno de los módulos es que puedes importar clases, funciones, objetos, etc., de un módulo a otro. Por ejemplo, podrías importar una función llamada xyz desde my-helper a otros módulos usando una declaración import de la siguiente manera:

// javascripts/discourse/controllers/my-theme-controller.js

import { xyz } from "discourse/helpers/my-helper";

La PR que voy a fusionar la próxima semana añadirá un prefijo a las rutas de los módulos de los temas. Así que en nuestro ejemplo, my-helper cambiará de discourse/helpers/my-helper a discourse/theme-<theme_id>/helpers/my-helper. Esto significa que nuestra declaración import dejará de funcionar porque la ruta del módulo habrá cambiado. Para solucionarlo, simplemente necesitamos cambiar la ruta en la declaración import de absoluta a relativa de la siguiente manera:

// javascripts/discourse/controllers/my-theme-controller.js

import { xyz } from "../helpers/my-helper";

Y ahora nuestra declaración import debería funcionar de nuevo. Consulta estas PRs 1 y 2 para ver ejemplos reales de componentes afectados por el punto (2) y cómo se solucionaron.

Nuevamente, esto solo afecta a tu tema o componente si importa desde uno de sus propios módulos; importar módulos principales no se ve afectado por este cambio.

Espero que esto ayude. Si tienes alguna pregunta, ¡por favor házmelo saber!

31 Me gusta

¡Gracias por el detallado informe! :slight_smile:

¿Esto afectará las rutas “absolutas” a archivos en un plugin utilizado en un componente de tema? Por ejemplo, los componentes de tema que funcionan con el plugin layouts requieren todos los helpers en el propio plugin layouts de esta manera:

requirejs('discourse/plugins/discourse-layouts/discourse/lib/layouts')

Véase, por ejemplo, el widget de lista de categorías de layouts.

Parece que el cambio de ruta aquí lo alinea con la organización en espacios de nombres de los activos en la tubería de activos del plugin (usando IDs de tema en lugar de nombres de plugins), y que las rutas de activos del plugin utilizadas en un componente de tema permanecerán igual. Y que un require como el anterior seguirá funcionando. ¿Es correcto?

7 Me gusta

Sí, eso es correcto :+1:

6 Me gusta

@loginerror, creo que encontrarás este tema útil :wink:

7 Me gusta

@Terrapop
Creo que tenías inquietudes al respecto.

5 Me gusta

Ya corregimos nuestro código cuando esto se publicó por tiempo limitado.

5 Me gusta