(Quand je dis Angular, je veux dire Angular 2+ et je dirai explicitement angular-js si je mentionne angular 1).
Prélude : C'est confus
Angular, et probablement plus précisément angular-cli, a fusionné un certain nombre d'outils tendance en Javascript qui sont impliqués dans le processus de construction. Cela conduit à un peu de confusion.
Pour ajouter à la confusion, le terme compile
était souvent utilisé dans angular-js pour désigner le processus consistant à prendre le pseudo-html du modèle et à le transformer en éléments DOM. C'est une partie de ce que fait le compilateur, mais une des plus petites parties.
Tout d'abord, il n'est pas nécessaire d'utiliser TypeScript, angular-cli ou Webpack pour exécuter Angular. Pour répondre à votre question. Nous devrions examiner une question simple : "Qu'est-ce qu'Angular ?"
Angulaire : Que fait-il ?
Cette section peut être controversée, nous le verrons. Le service offert par Angular consiste essentiellement en un mécanisme d'injection de dépendances qui fonctionne en Javascript, HTML et CSS. Vous écrivez tous les petits morceaux individuellement et dans chaque petit morceau vous suivez les règles d'Angular pour référencer les autres morceaux. Angular tisse ensuite l'ensemble d'une manière ou d'une autre.
Pour être (légèrement) plus précis :
- Les modèles permettent de connecter le HTML au composant Javascript. Cela permet à l'utilisateur d'entrer dans le DOM lui-même (par exemple, en cliquant sur un bouton) pour alimenter le composant Javascript et permet également aux variables du composant Javascript de contrôler la structure et les valeurs du DOM.
- Les classes Javascript (y compris les composants Javascript) doivent pouvoir accéder aux instances d'autres classes Javascript dont elles dépendent (par exemple, injection de dépendance classique). Un BookListComponent a besoin d'une instance d'un BookListService qui peut avoir besoin d'une instance d'un BookListPolicy ou quelque chose comme ça. Chacune de ces classes a une durée de vie différente (par exemple, les services sont généralement des singletons, les composants ne sont généralement pas des singletons) et Angular doit gérer toutes ces durées de vie, la création des composants et le câblage des dépendances.
- Les règles CSS devaient être chargées de telle sorte qu'elles ne s'appliquent qu'à un sous-ensemble du DOM (le style d'un composant est local à ce composant).
Il est important de noter qu'Angular n'est pas responsable de la manière dont les fichiers Javascript font référence à d'autres fichiers Javascript (par exemple, la balise import
mot-clé). C'est Webpack qui s'en charge.
Que fait le compilateur ?
Maintenant que vous savez ce que fait Angular, nous pouvons parler de ce que fait le compilateur. Je vais éviter d'être trop technique, principalement parce que je suis ignorant. Cependant, dans un système d'injection de dépendances, vous devez généralement exprimer vos dépendances à l'aide d'une sorte de métadonnées (par exemple, comment une classe disant I can be injected
, My lifetime is blah
ou You can think of me as a Component type of instance
). En Java, Spring a initialement fait cela avec des fichiers XML. Java a ensuite adopté les annotations, qui sont devenues le moyen privilégié d'exprimer les métadonnées. C# utilise des attributs pour exprimer les métadonnées.
Javascript n'a pas un grand mécanisme pour exposer cette métadonnée intégrée. angular-js a fait une tentative et ce n'était pas mal mais il y avait beaucoup de règles qui ne pouvaient pas être facilement vérifiées et étaient un peu confuses. Avec Angular, il existe deux façons de spécifier les métadonnées. Vous pouvez écrire du Javascript pur et spécifier les métadonnées manuellement, un peu comme avec angular-js et continuer à suivre les règles et à écrire du code supplémentaire. Vous pouvez également passer à TypeScript qui, comme par hasard, dispose de décorateurs (ces @
) qui sont utilisés pour exprimer les métadonnées.
C'est donc ici que nous pouvons enfin passer au compilateur. Le travail du compilateur consiste à prendre ces métadonnées et à créer le système de pièces fonctionnelles qu'est votre application. Vous vous concentrez sur toutes les pièces et toutes les métadonnées et le compilateur construit une grande application interconnectée.
Comment le compilateur s'y prend-il ?
Le compilateur peut travailler de deux façons : en cours d'exécution et en avance sur le temps. À partir de maintenant, je supposerai que vous utilisez TypeScript :
-
Durée d'exécution : Lorsque le compilateur TypeScript s'exécute, il prend toutes les informations relatives aux décorateurs et les insère dans le code Javascript associé aux classes, méthodes et champs décorés. Dans votre
index.html
vous faites référence à votre main.js
qui appelle le bootstrap
méthode. Cette méthode est transmise à votre module de premier niveau.
La méthode bootstrap lance le compilateur d'exécution et lui donne une référence à ce module de premier niveau. Le compilateur d'exécution commence alors à explorer ce module, tous les services, composants, etc. référencés par ce module, ainsi que toutes les métadonnées associées, et construit votre application.
-
AOT : Plutôt que de faire tout le travail au moment de l'exécution, Angular a fourni un mécanisme permettant de faire la majeure partie du travail au moment de la construction. Ceci est presque toujours fait en utilisant un plugin webpack (ce doit être l'un des paquets npm les plus populaires et pourtant les moins connus). Il s'exécute après la compilation des typescripts et voit donc essentiellement la même entrée que le compilateur d'exécution. Le compilateur AOT construit votre application comme le compilateur d'exécution, mais l'enregistre ensuite en Javascript.
L'avantage ici n'est pas seulement d'économiser le temps CPU nécessaire à la compilation elle-même, mais aussi de réduire la taille de votre application.
Réponses spécifiques
Angular CLI appelle d'abord le compilateur intégré d'angular écrit en Typescript => puis appelle le transpilateur Typescript => puis appelle la fonction Webpack pour regrouper et stocker dans le répertoire dist/.
Non. Angular CLI appelle Webpack (le vrai service d'Angular CLI est la configuration de webpack. Lorsque vous exécutez ng build
ce n'est pas beaucoup plus qu'un proxy pour démarrer Webpack). Webpack appelle d'abord le compilateur Typescript, puis le compilateur Angular (dans l'hypothèse d'un AOT), tout en regroupant votre code en même temps.
Bien que main.ts soit utilisé dans la déclaration ci-dessus pour expliquer le processus d'amorçage. l'application angulaire n'est-elle pas amorcée ou démarrée à l'aide de fichiers Javascript .js ?
Je ne suis pas tout à fait certain de ce que vous demandez ici. main.ts
sera transposé en Javascript. Ce Javascript contiendra un appel à bootstrap
qui est le point d'entrée dans Angular. Lorsque bootstrap
est fait, vous aurez votre application Angular complète en cours d'exécution.
Ce post dit qu'Angular a deux compilateurs :
Voir le compilateur
Compilateur de modules
Pour être honnête, je vais juste clamer mon ignorance ici. Je pense qu'à notre niveau, nous pouvons simplement considérer tout cela comme un grand compilateur.
Quelqu'un sait-il comment toutes les pièces s'assemblent en profondeur ?
J'espère que ce qui précède vous a satisfait.
Don't @ Me : Angular fait plus que de l'injection de dépendances
Bien sûr. Il fait du routage, de la construction de vues, de la détection de changement et toutes sortes d'autres choses. Le compilateur génère en fait du Javascript pour la construction des vues et la détection des changements. J'ai menti quand j'ai dit que c'était juste l'injection de dépendance. Cependant, l'injection de dépendances est au cœur du système et suffit à piloter le reste de la réponse.
Devrions-nous l'appeler un compilateur ?
Il fait probablement beaucoup de parsing et de lexing et génère certainement beaucoup de code en conséquence, on peut donc l'appeler un compilateur pour cette raison.
D'autre part, il ne s'agit pas vraiment de traduire votre code en une représentation simplement différente. Il s'agit plutôt de prendre un tas de morceaux de code différents et de les tisser en morceaux consommables d'un plus grand système. Le processus d'amorçage prend ensuite (après compilation, si nécessaire) ces morceaux et les intègre au noyau d'Angular.