Comment configurer et améliorer le build d'une application Aurelia via le plugin aurelia-webpack-plugin ?
Pour tout vous dire et sans trop forcer hier soir, en reparamétrant le build d'un des projets de @Lenny et @Kysofer, la taille du bundle JS s'est réduite de 12,8% et au vu de mes tests, nous devrions êtres en mesure de récupérer 15% à 20% de plus.
Cela fait de nos SPA que leurs pages d'accueil ne dépassent jamais les 685 Ko tout compris (ie. HTML + JS + CSS + IMG + FONTS) et moins de 180 Ko en utilisant une compression Gzip sur les fichiers statiques.
En ajoutant à cela un cycle de release non continu pour ne pas perdre les bénéfices de la mise en cache côté navigateurs, nous nous retrouvons avec une page de garde ne requérant plus que 3,6 Ko à télécharger lors de la seconde connexion et des suivantes.
Essayez d'en faire autant avec Angular et Bootstrap ! Je maintiens que le combo TypeScript + SCSS + Aurelia + Bulma + Karla Fonts + Font Awesome + TinyPNG est le plus efficace. J'ai vraiment hâte de passer à Aurelia 2 en 2020 !!! ٩(◕‿◕。)۶
Réduire la taille de son bundle JS en supprimant les dépendances inutilisées. Fonctionne pour Vue.js mais doit aussi fonctionner pour Aurelia.
Et encore une fois, ce lien est remonté par Kalvn.
Comprendre le fonctionnement du lazy-loading en Webpack (le tuto s'appuie sur Vue.js mais fonctionne aussi pour d'autres frameworks comme Aurelia.io).
Et encore une fois c'est à Kalvn que l'on doit ce super lien.
Si vous utilisiez le plugin gulp-webpack
il vaut mieux passer à webpack-stream
qui est son remplaçant. Pour l'instant, j'utilise Webpack à travers Gulp à la main, mais si webpack-stream
est efficace et réduit la quantité de code des mes tâches Gulp, alors je migrerai.
Je vais faire ma reloue, mais je vous assure qu'écrire du code pour builder du code est une hérésie. Dommage qu'il n'y ait pas de plugin Aurelia pour Brunch.
Une explication montrant l'évolution de la stack JS depuis 2010 et pourquoi autant d'outils ont fait leur apparition depuis.
Bon, je dois refaire du Webpack pour mettre à jour le build d'un tool de la boite. Comme j'ai eu beaucoup de peine à retrouver comment et quoi faire, voici un bref résumé des trucs et astuces à connaître sur Webpack.
Comment concaténer des fichiers JS inter-dépendants ?
Principe : mon fichier JS (Main.js) importe d'autres fichiers JS (cf. le mot-clef require de TypeScript / ES6). Et ces fichiers JS importent également d'autres fichiers. L'idée ici est d'avoir un Webpack qui parcours le graphe des dépendances en analysant le code afin de produire un et un seul fichier JS qui n'inclut que ce dont mon application se sert.
Contenu du fichier webpack.conf.js :
module.exports = {
entry: {
Car : './src/Main.js' // Charge ce fichier ainsi que tous ceux dont il dépend via le mot-clef 'require'.
},
output: {
path: './target',
filename: 'merged-file.js'
}
};
Comment créer un bundle de fichiers JS qui n'ont aucune dépendance entre-eux ?
Principe : j'ai plein de libs écrites en JavaScript avec mes petites mimines (ou pas), ces librairies n'ont aucune dépendance entre-elles, cependant je souhaiterais les concaténer dans un gros bundle de sorte à minimiser le nombre de requêtes réseau.
Contenu du fichier webpack.conf.js :
module.exports = {
entry: [
'./src/Car.js', // La liste des fichiers à concaténer
'./src/Vehicule.js'
],
output: {
path: './target',
filename: 'merged-file.js'
}
};
Comment créer plusieurs bundles de fichiers JS qui n'ont aucune dépendance entre-eux ?
Principe : je reprends les fichiers JS du point précédent à ceci près que je souhaite créer plusieurs bundles, un pour chaque types de véhicules par exemple.
Contenu du fichier webpack.conf.js :
module.exports = {
entry: {
four-wheels : [
'./src/Car.js',
'./src/Vehicule.js'
],
two-wheels : [
'./src/Bike.js',
'./src/Vehicule.js'
]
},
output: {
path: './target',
filename: '[name].bundle.js',
chunkFilename : '[id].bundle.js'
}
};
Comment minifier mes bundles JS ?
Principe : mes fichiers JS sont gros et je souhaite supprimer le maximum d'espace, les commentaires, réduire le nom des fonctions, variables & Co de sorte à fournir le plus petit fichier possible.
Contenu du fichier webpack.conf.js :
var webpack = require("webpack");
module.exports = {
entry: [
'./src/Car.js',
'./src/Vehicule.js'
],
output: {
path: './target',
filename: 'app.minified.js'
},
plugins: [
new webpack.optimize.UglifyJsPlugin({minimize: true})
]
};
Pourquoi ce tuto ?
Grosso-modo je dois apprendre comment reproduire un build Maven mais en JS avec les outils JS qui vont bien ; et qui soient plus ou moins les standards de facto du moment (i.e en ce début 2017).
Définitions :
À quoi sert quel outil dans ce gloubi-boulga d'outils tous plus hypes les uns que les autres ?
NodeJS :
C'est une machine virtuelle qui permet de faire tourner du JavaScript côté serveur.
NPM :
C'est le gestionnaire de paquets permettant de récupérer les dépendances transitives de vos projets (façon Maven). Certains disent que NPM signifie Node Package Manager mais l'auteur atteste que non.
Yarn :
NPM c'est top, mais ça possède trois inconvénients :
- La ligne de commande pu des fesses.
- NPM ne sait pas mettre les paquets dans un répo local (comme le fait a contrario Maven), donc NPM passe son temps à re-télécharger les dépendances qu'il a déjà téléchargé pour le projet précédent.
- NPM ne gère pas le build concurrent (il n'est pas multi-threadé) donc le build rame (enfin tout est relatif #CompilationC++).
Yarn est un outils qui réponds à ces trois problématiques avec un chat tout mimi en guise de logo.
TypeScript :
C'est à la fois un langage mais également un compilateur éponyme. En gros, les mecs de Microchiotte se sont dits que JavaScript ça ne sentait pas bon des fesses (comme la ligne de commande de NPM) et qu'il valait mieux coder avec de vraies classes, des vrais namespaces, de vraies visibilités (public, private, etc) et une fois que tout ceci était correctement codé en TypeScript, ont transpile ce code en du JavaScript ; autrement dit on convertir le code du TypeScript dans une syntaxe cohérente et fortement typée, vers du JS (incohérent et faiblement typé) ; et comme cela plus besoin de se prendre la tête à connaître tous les hacks de ce langage merdique (une référence ici sur la merdicitude de JS et une autre là sur la retard community - ces deux articles sont pour toi Lenny).
Jasmine :
C'est un framework permettant d'écrire des tests en JavaScript. Ces derniers peuvent être au niveau unitaire (façon JUnit) ou fonctionnel / intégration (façon Cucumber). En général Jasmine est considéré comme faisant partie des framework destinés au BDD (mais bon, je ne suis pas d'accord).
Karma :
Un outil permettant de charger une suite de tests écrits en Jasmine ou en tout autre chose. Le concurrent le plus sérieux est MochaJS qui est une sorte de medley entre Karma et Jasmine, mais comme je n'ai pas encore eu le temps de l'étudier,que Karma à l'avantage d'être soutenu par les développeurs Google qui bossent sur Angular 2 et que j'ai déjà utilisé Jasmine par le passé... Bah Karma & Jasmine.
PhantomJS :
NodeJS permet d'exécuter du JavaScript côté serveur, et bien PhantomJS est un navigateur sans interface graphique permettant d'exécuter du JavaScript dans une console afin de le tester (ndr. en s'appuyant sur Jasmine et Karma). Vous vous doutez bien qu'un navigateur sans IHM est un navigateur ultra-rapide pour faire tourner du JS (sous-entendu parfait pour avoir des phases de run de TU rapides durant nos builds).
Webpack :
Webpack peut quasiment tout faire à l'aide de ses plugins mais l'idée ici est de s'en servir pour trois choses :
- Packager l'ensemble du JS dans un seul fichier qui soit unique.
- Minifier au taquet ce fichier packagé.
- Ne pas inclure dans le package minifié le code mort, c'est-à-dire les classes qui ne sont jamais chargées directement ou transitivement par la classe Main.
Et donc dans tout ça ? Et bien dans tout cela vous aurez donc un build JS qui va chercher les dépendances tout seul, qui respecte le cycle de vie de Maven, qui assure la séparation du code à livrer (les sources) du code à ne pas livrer (les plugins du build et le code des tests), qui centralise la production des binaires en un seul endroit et qui soit capable de releaser votre build (i.e fabriquer des tags et incrémenter le numéro de version). Pas mal hein ?
La suite des posts à lire figure ici (en cours de complétion) :
Je précise ici que je cherche à reproduire l'architecture de dossier et le life-cycle de Maven mais pour un projet NodeJS / Aurelia. Nous allons donc avoir ce type de dossiers :
. (root folder) # La racine du répo
|__ node_modules/ # Le répertoire des éléments téléchargés par NPM
|
|__ src/ # Le répertoire contenant les sources
| |__ main/ # Les sources qui seront livrées
| | |__ js/
| |
| |__ test/ # Les sources qui ne seront jamais livrées (les tests)
| |__ js/
|
|__ target/ # Le répertoire contenant les éléments générés lors de build
|
|_ karma.conf.js # Le fichier de configuration de Karma (le générateur de suite de tests)
|_ package.js # Le fichier de configuration de Yarn (le build manager)
|_ tsconfig.json # Le fichier de configuration de TypeScript (le transpilateur)
|_ webpack.config.js # Le fichier de configuration de Webpack (le packager / minifier)
- Comment installer et configurer NodeJS & NPM
- Comment installer et configurer le transpilateur TypeScript ?
C'est partiiii #JoueLaCommeBarnabé
Un tuto pour faire du NPM + WebPack + TypeScript + React. Je ferai un résumé de la conf plus tard (si j'ai le temps).
Un tutoriel assez complet expliquant comment utiliser TypeScript avec Webpack. NPM ne sert plus qu'à rapatrier les dépendances dans le répertoire node_modules