Différer le chargement de JavaScript dans les thèmes et composants

Grâce à @david, nous disposons d’un modèle très propre pour le chargement « eager » de JavaScript dans les thèmes.

Cela signifie que vous n’avez qu’à placer les fichiers *.js.es6 dans le répertoire javascripts et cela fonctionne exactement comme pour les plugins, ce qui est formidable.

Par exemple, voici comment créer un initialiseur maintenant, avec une parité à 100 % avec les plugins :

  • Créez un fichier nommé /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);
  }
};

Il s’agit d’une fonctionnalité extrêmement importante car nous pouvons désormais diviser les grands thèmes complexes en de nombreuses parties, bénéficier du linting, de la coloration syntaxique et de tout le reste.

Cependant, dans certains cas, nous pourrions vouloir optionnellement livrer un payload JS.

Par exemple, disons que nous décorons les publications, mais uniquement celles contenant du markdown très spécifique. Il n’y a aucun intérêt à télécharger une bibliothèque complexe de 100 Ko tant que nous ne savons pas que nous allons l’utiliser.

J’ai contourné ce problème dans mon composant en suivant ce changement élégant :

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

Avec :

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

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

Cela signifiait :

  1. J’ai dû ajouter .js aux « extensions autorisées pour les thèmes »
  2. J’ai dû ajouter une exception à la CSP pour l’actif particulier dans « content security policy script src »
  3. J’ai dû nommer l’actif dans mon about.json

En tant qu’auteur de composant de thème, c’est tout simplement trop de friction car vous n’avez aucune chance dans le jeu de la distribution en exigeant un tel niveau de compétence de ninja.

Je pense que pour rendre cela utilisable, nous avons deux alternatives parmi lesquelles choisir :

  1. Nous pouvons enseigner au système d’appliquer automatiquement la CSP aux actifs .js dans les thèmes actifs et, par défaut, autoriser les thèmes à télécharger des .js

  2. Nous pouvons nous orienter vers quelque chose comme javascript_cache que les thèmes non différés utilisent pour le JS.

Je penche plutôt vers la solution 1 car ajouter .js aux extensions autorisées pour les thèmes semble trivial et l’application automatique de la CSP ne devrait pas être impossible.

@pmusaraj / @Johani / @Osama, avez-vous des idées à ce sujet ?

10 « J'aime »

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 « J'aime »

Réactivation car la seule chose qui reste ici est d’apprendre à CSP à autoriser les téléchargements de thèmes js. Les fichiers js sont autorisés par défaut comme téléchargements de thèmes depuis un certain temps.

Si les téléchargements de thèmes js ne sont pas bloqués par CSP, alors des composants comme Image Annotator - Allows you to annotate images in the previewer n’auront pas besoin de charger leurs dépendances sur la page d’accueil (~170 Ko compressés). Ce composant, par exemple, n’aura besoin de charger ces dépendances que lorsque le compositeur sera ouvert. De plus, il n’aura jamais besoin de les charger pour les visiteurs anonymes.

De plus, ce changement « autoriserait » les thèmes à avoir des fichiers web worker qui peuvent effectuer des tâches lourdes hors du thread principal.

Autoriser entre guillemets ci-dessus car vous pouvez les avoir sous forme de blobs, mais il est beaucoup plus agréable de les avoir dans des fichiers séparés au lieu de bricoler avec du javascript dans une chaîne.

4 « J'aime »

J’ai une bonne nouvelle, c’est un peu compliqué à mettre en œuvre mais nous allons enfin prendre en charge les ressources JS locales pour les cas où nous voulons utiliser des web workers dans les composants de thème.

Il n’y a pas d’autre moyen propre de faire passer cela par le CSP, servir les fichiers worker du même domaine résout le problème majeur ici.

3 « J'aime »

Note… ceci a maintenant été expédié :confetti_ball:

5 « J'aime »