Modifiche fondamentali in arrivo: possibili problemi per temi/componenti (12 aprile)

La prossima settimana unirò questa PR che consente ai temi e ai componenti di avere test QUnit, ma modifica anche il modo in cui Discourse elabora/traspile il JavaScript dei temi. Realizzare queste modifiche in modo retrocompatibile è molto difficile senza riprogettare gran parte del codice nel core (il che potrebbe introdurre altre modifiche non retrocompatibili), quindi le modifiche potrebbero rompere il JavaScript dei tuoi temi/componenti quando aggiorni il tuo sito.

In questo post spiegherò quali sono le modifiche che potrebbero influenzare i tuoi temi/componenti e cosa devi fare per correggerle.

1. Il JavaScript all’interno dei tag <script type="text/discourse-plugin"> verrà eseguito con la modalità strict abilitata

Questa modifica non influisce sul codice JS che non si trova all’interno dei tag <script type="text/discourse-plugin">. Se il tuo codice è in normali tag <script> o in file .js autonomi, sei completamente al sicuro da questa modifica.

Il modo più semplice per capire se il tuo tema/componente è influenzato da questa modifica è avvolgere il tuo codice JS in una Immediately-Invoked Function Expression (IIFE) e inserire "use strict"; all’inizio del codice. Ad esempio, supponiamo che il tuo codice tema appaia così attualmente:

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

Dopo averlo avvolto in un IIFE, dovrebbe apparire così ("use strict"; è importante perché abilita la modalità strict e vogliamo testare come si comporta il nostro codice in questa modalità):

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

Se il tuo componente smette di funzionare dopo aver fatto questo, allora si romperà quando aggiornerai il tuo sito. Per correggere il tuo codice, ti consiglio vivamente di leggere prima la documentazione MDN per la modalità strict di JavaScript e poi verificare se il tuo tema/componente esegue azioni proibite in modalità strict. Se lo fa, dovrai rifattorizzare il tuo codice in modo che non esegua azioni proibite.

L’errore più probabile che vedrai è ReferenceError quando dichiari una variabile senza la parola chiave var (o let/const). Nell’esempio sopra, la riga a = 5; lancerà un’eccezione ReferenceError in modalità strict perché abbiamo dimenticato di aggiungere var. Il codice, dopo la correzione, apparirà così:

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

Una volta completati i test e le correzioni del tuo codice, sentiti libero di rimuovere l’IIFE e la riga "use strict";.

2. I percorsi dei moduli JavaScript dei temi saranno preceduti dagli ID del tema.

Qualche tempo fa abbiamo aggiunto una nuova funzionalità che permetteva al JavaScript dei temi di essere diviso in più file, e devo fornire un po’ di contesto su questa funzionalità per spiegare la modifica imminente.

Quando un tema/componente che include file JavaScript autonomi viene installato su un’istanza di Discourse, Discourse itera su tutti i file JavaScript e crea un modulo JavaScript per ciascuno. Ogni modulo deve avere un identificatore univoco (noto anche come percorso), quindi Discourse utilizza il percorso del file (con piccole modifiche) come percorso del modulo.

Ad esempio, se il tuo tema/componente ha un file in javascripts/discourse/helpers/my-helper.js, Discourse creerà un modulo per quel file e assegnerà discourse/helpers/my-helper come suo percorso, e il modulo conterrà una versione traspile del JavaScript presente nel file originale.

La cosa positiva dei moduli è che puoi importare classi/funzioni/oggetti ecc. da un modulo in un altro. Ad esempio, potresti importare una funzione chiamata xyz da my-helper in altri moduli utilizzando un’istruzione import come questa:

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

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

La PR che unirò la prossima settimana aggiungerà un prefisso ai percorsi dei moduli dei temi. Quindi, nel nostro esempio, my-helper cambierà da discourse/helpers/my-helper a discourse/theme-<theme_id>/helpers/my-helper. Ciò significa che la nostra istruzione import smetterà di funzionare perché il percorso del modulo sarà cambiato. Per correggerlo, dobbiamo semplicemente cambiare il percorso nell’istruzione import da assoluto a relativo, come segue:

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

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

E ora la nostra istruzione import dovrebbe funzionare di nuovo. Consulta queste PR 1 e 2 per esempi reali di componenti influenzati dal punto (2) e su come sono stati corretti.

Ancora una volta, questo influisce sul tuo tema/componente solo se importa da uno dei suoi stessi moduli; l’importazione di moduli core non è influenzata da questa modifica.

Spero che questo sia d’aiuto. Se hai domande, fammelo sapere!

31 Mi Piace

Grazie per il resoconto dettagliato :slight_smile:

Questo influenzerà i percorsi “assoluti” ai file in un plugin utilizzato in un componente del tema? Ad esempio, i componenti del tema che funzionano con il plugin layouts richiedono tutti helper nello stesso plugin layouts in questo modo:

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

Vedi ad esempio, il widget elenco categorie layouts.

Sembra che la modifica del percorso qui lo allinei alla namespace degli asset nella pipeline degli asset del plugin (utilizzando gli ID del tema invece dei nomi del plugin), e che i percorsi degli asset del plugin utilizzati in un componente del tema rimarranno invariati. E che un require come quello sopra continuerà a funzionare. È corretto?

7 Mi Piace

Sì, è corretto :+1:

6 Mi Piace

@loginerror, credo che troverai utile questo argomento :wink:

7 Mi Piace

@Terrapop
Credo che tu avessi delle preoccupazioni al riguardo.

5 Mi Piace

Abbiamo già corretto il nostro codice quando è stato pubblicato per un periodo limitato.

5 Mi Piace