Moderne ECMAScript Syntax in Ext JS Projekten verwenden
Sencha Ext JS wird mit einem Closed-Source Build-Tool geliefert, welches den Closure Compiler beinhaltet; In einigen Fällen hindert dies Entwickler daran, moderne ECMAScript-Syntax zu verwenden. Dieser Artikel stellt @coon-js/delorean vor, ein Tool, das dieses Problem mithilfe zusätzlicher Transpilierung umgeht.
Leider versteht Ext JS nur ein Subset an moderner ECMAScript Syntax – bei der Entwicklung ist man gut damit beraten, ein Gemenge von ES5 und ES6 zu verwenden, damit der Build mit Sencha CMD auch funktioniert. Denn was im schlimmsten Fall passieren kann, ist: Sobald Sencha CMD ein Paket oder eine Anwendung baut, wird Code, der in dev oder während Tests funktionierte, nicht immer erfolgreich kompiliert, oder noch schlimmer: es wird JavaScript Source Code erstellt, der zwar initial lauffähig ist, im Live-Betrieb aber plötzliche Fehler wirft.
Bspw. ist folgender Source bekannt dafür, Sencha CMD Probleme zu bereiten:
Der Nullish coalescing operator:
const foo = null ?? "default string";
Destructuring assignment syntax mit Funktionsargumenten:
const fn = ([x, y, z]) => ({x, y, z});
Der Optional chaining operator:
const adventurer = {
name: "Alice",
cat: {
name: "Dinah"
}
};
const dogName = adventurer.dog?.name;
Der Grund dafür ist, dass Sencha CMD ein proprietäres Tool ist, das den Closure Compiler als Abhängigkeit integriert hat; leider bietet genau diese Abhängigkeit sowie die Art und Weise der Konfiguration der Tools untereinander keine Möglichkeit, Build-Prozesse weiter zu optimieren. Außerdem benötigt der Closure Compiler offensichtlich Updates, um aktuelle ECMAScript-Standards verstehen zu können. Es gibt zwar einige Konfigurationsoptionen, die ein nachsichtigeres (sprich: kompatibles) Parsen und Transpilieren des Quellcodes ermöglichen. Allerdings gibt es Code, der das Kompilieren verhindert, selbst wenn der Code syntaktisch korrekt ist.
(Diese Übersicht enthält eine Liste, in der Kompatibilitäten zu Sprachstandards aufgeführt sind.)
Erwähnenswert ist außerdem, dass die neueste verfügbare Version des Closure Compilers nicht unbedingt mit der neuesten verfügbaren Version von Sencha CMD ausgeliefert wird: v7.6.0.87 von Sencha CMD wird mit v20220301 ausgeliefert:
@sencha\cmd> dir /s/b | findstr .*closure.*$
@sencha\cmd\dist\lib\closure-compiler-externs-v20220301.jar
@sencha\cmd\dist\lib\closure-compiler-v20220301.jar
Wenn etwas schief gehen kann...
Im folgenden betrachten wir ein Beispiel, das zeigt, wie korrekter JavaScript Code ein nicht lauffähiges Ext JS-Projekts verursacht:
const fn = ([a, b, c]) => ({a, b, c});
Diese Pfeilfunktion
- benutzt destrukturierende Zuweisung um die ersten 3 Einträge eines Arrays zu entpacken
- erstellt dann ein Objekt basierend auf diesen Einträgen mit Hilfe der shorthand notation für Eigenschaftsnamen
- Liefert das erzeugte Objekt zurück
Dieser Code sei nun Teil eines Ext JS Packages, das mit folgendem Befehl gebaut wird:
npx @sencha/cmd package build
Die verwendete Sencha CMD Version ist:
npx @sencha/cmd which
Sencha Cmd v7.6.0.87
Die Konfiguration der sencha Sektion aus der package.json sieht folgendermaßen aus:
"output": {
"base": "${package.dir}/build"
},
"compressor": {
"type": "closure",
"polyfills": "none"
},
Das Kompilieren schlägt fehl, da das output level per default auf ES5 gesetzt ist; es ist ein älterer ECMAScript Standard, der aber von von den meisten gängigen Browsern verstanden wird: