Retrasar la carga de JavaScript en Temas y Componentes

Gracias a @david, tenemos un patrón muy limpio para la carga “eager” de JavaScript en los temas.

Esto significa que solo tienes que colocar archivos *.js.es6 en el directorio javascripts y funcionará exactamente como lo hacen los plugins; esto es glorioso.

Por ejemplo, así es como ahora se crea un inicializador, con una paridad del 100% con los plugins:

  • Crea un archivo llamado /javascripts/discourse/initializers/my-init.js.es6
import { withPluginApi } from "discourse/lib/plugin-api";

function initialize(api) {
  // init via api here
}

export default {
  name: "discourse-otp",

  initialize() {
    withPluginApi("0.8.28", initialize);
  }
};

Esta es una característica enormemente importante porque ahora podemos dividir temas grandes y complejos en muchas partes, obtener linting, resaltado de sintaxis y todas las cosas buenas.

Sin embargo, en algunos casos podemos querer enviar opcionalmente una carga útil de JS.

Por ejemplo, digamos que estamos decorando publicaciones, pero solo aquellas con un markdown muy específico. No tiene sentido descargar una biblioteca sofisticada de 100KB hasta que sepamos que la vamos a usar.

En mi componente, trabajé alrededor de esto siguiendo este cambio elegante:

https://github.com/discourse/discourse/commit/719a93c312b9caa6c71de22d67f1ce1a78c1c8b2

Con:

import loadScript from "discourse/lib/load-script";

function generateOtp($elem) {
  loadScript(settings.theme_uploads.jsotp).then(() => {
     // stuff goes here
  });
}

Esto significó que:

  1. Necesitaba agregar .js a theme authorized extensions (extensiones autorizadas del tema).
  2. Necesitaba agregar una excepción a la CSP para el activo particular en content security policy script src.
  3. Necesitaba nombrar el activo en mi about.json.

Como escritor de componentes de temas, esto es demasiada fricción, ya que no tienes ninguna posibilidad en el juego de distribución si requieres este nivel de ninja.

Estoy pensando que, para hacer esto utilizable, hay 2 alternativas de las que podemos elegir:

  1. Podemos enseñar al sistema a aplicar CSP automáticamente a los activos .js en temas activos y, por defecto, permitir que los temas suban .js.

  2. Podemos movernos hacia algo como javascript_cache que usan los temas JS no diferidos.

Me inclino un poco hacia la opción 1, ya que agregar .js a las extensiones autorizadas del tema parece trivial y el CSP automático no debería ser imposible.

@pmusaraj / @Johani / @Osama, ¿alguna opinión al respecto?

10 Me gusta

The ability to reference theme uploads in JS is a great addition! :100:

This makes a lot of sense to me because anything you can do in a .js file can already be done in files in the javascripts folder of the theme. So, I don’t see any harm in allowing themes to have .js uploads by default.

7 Me gusta

Reviviendo esto porque lo único que queda aquí es enseñar a CSP a permitir cargas de js de temas. Los archivos js han sido permitidos por defecto como cargas de temas desde hace un tiempo.

Si las cargas de js de temas no están bloqueadas por CSP, entonces componentes como Image Annotator - Allows you to annotate images in the previewer no necesitarán cargar sus dependencias en la página de inicio (~170kb comprimido). Ese componente, por ejemplo, solo necesitará cargar esas dependencias si se abre el compositor. Además, nunca necesita cargarlas para los espectadores anónimos.

También, este cambio “permitiría” que los temas tengan archivos de web worker que pueden hacer un trabajo pesado fuera del hilo principal.

Permitir entre comillas arriba porque puedes tenerlos como blobs, pero es mucho más agradable tenerlos en archivos separados en lugar de jugar con javascript en una cadena.

4 Me gusta

Tengo buenas noticias, es un poco complicado de implementar pero por fin vamos a admitir activos JS locales para los casos en los que queramos usar web workers en componentes de temas.

No hay otra forma limpia de superar esto a través de CSP, servir archivos de worker desde el mismo dominio resuelve el gran problema aquí.

3 Me gusta

Nota… ¡esto ya se ha enviado :confetti_ball:!

5 Me gusta