Wie Angular baut und läuft

84

Möchten Sie nur erfahren, wie Angular hinter den Kulissen baut und läuft?

Unten ist das, was ich bisher verstanden habe. Willst du wissen, ob ich etwas verpasst habe?

Wie Angular baut

Nachdem wir unsere Angular-Apps mit TypeScript codiert haben, verwenden wir den Angular CLI-Befehl, um die App zu erstellen.

ng buildDer Befehl kompiliert die Anwendung in ein Ausgabeverzeichnis und die Build-Artefakte werden im dist/Verzeichnis gespeichert .

Interner Prozess

1. Angular CLI führt Webpack aus, um den gesamten JavaScript- und CSS-Code zu erstellen und zu bündeln.

2. Webpack ruft wiederum die TypeScript-Loader auf, die alle .tsDateien im Angular-Projekt abrufen und sie dann in JavaScript umwandeln, dh in eine .jsDatei, die Browser verstehen können.

Dieser Beitrag besagt, dass Angular zwei Compiler hat:

  • Compiler anzeigen

  • Modul-Compiler

Fragen zu Builds

Wie wird der Build-Prozess aufgerufen?

Angular CLI ruft zuerst den in TypeScript geschriebenen integrierten Angular-Compiler auf => ruft dann den TypeScript-Transpiler auf => ruft dann das Webpack auf, um es zu bündeln und im dist/Verzeichnis zu speichern .

Wie Angular läuft

Nach Abschluss der Erstellung werden alle Komponenten, Dienste, Module usw. unserer App in JavaScript .jsDateien übertragen, mit denen die Angular-Anwendung im Browser ausgeführt wird.

Anweisungen in Angular Docs

  1. Wenn Sie mit der AppComponentKlasse (in main.ts) booten, sucht Angular nach a <app-root>in index.html, findet es, instanziiert eine Instanz von AppComponent und rendert es innerhalb des <app-root>Tags.

  2. Angular erstellt, aktualisiert und zerstört Komponenten, während sich der Benutzer durch die Anwendung bewegt.

Fragen zu Läufen

Obwohl main.tsin der obigen Anweisung zur Erläuterung des Bootstrap-Prozesses verwendet wird, wird die Angular-App nicht mit JavaScript- .jsDateien gebootet oder gestartet ?

Werden nicht alle oben genannten Anweisungen zur Laufzeit mit JavaScript- .jsDateien ausgeführt?

Weiß jemand, wie alle Teile in der Tiefe zusammenpassen?

Shaijut
quelle

Antworten:

89

(Wenn ich Angular sage, meine ich Angular 2+ und sage explizit Angular-js, wenn ich Angular 1 erwähne).

Vorspiel: Es ist verwirrend

Angular und wahrscheinlich genauer Angular-Cli haben eine Reihe von Trendwerkzeugen in Javascript zusammengeführt, die am Erstellungsprozess beteiligt sind. Es führt zu ein wenig Verwirrung.

Um die Verwirrung zu compilefördern , wurde der Begriff häufig in Angular-Js verwendet, um den Prozess zu bezeichnen, bei dem das Pseudo-HTML der Vorlage in DOM-Elemente umgewandelt wird. Das ist ein Teil dessen, was der Compiler macht, aber einer der kleineren Teile.

Zunächst müssen Sie TypeScript, Angular-Cli oder Webpack nicht verwenden, um Angular auszuführen. Zur Beantwortung Ihrer Frage. Wir sollten uns eine einfache Frage ansehen: "Was ist Angular?"

Angular: Was macht es?

Dieser Abschnitt kann kontrovers sein, wir werden sehen. Im Kern ist der von Angular bereitgestellte Dienst ein Mechanismus zur Abhängigkeitsinjektion, der in Javascript, HTML und CSS funktioniert. Sie schreiben alle kleinen Teile einzeln und befolgen in jedem kleinen Teil die Regeln von Angular, um auf die anderen Teile zu verweisen. Angular webt das dann irgendwie zusammen.

Um (etwas) genauer zu sein:

  • Mit Vorlagen kann HTML in die Javascript-Komponente eingebunden werden. Auf diese Weise können Benutzereingaben im DOM selbst (z. B. Klicken auf eine Schaltfläche) in die Javascript-Komponente eingegeben werden, und Variablen in der Javascript-Komponente können die Struktur und die Werte im DOM steuern.
  • Javascript-Klassen (einschließlich Javascript-Komponenten) müssen auf Instanzen anderer Javascript-Klassen zugreifen können, von denen sie abhängen (z. B. klassische Abhängigkeitsinjektion). Eine BookListComponent benötigt eine Instanz eines BookListService, die möglicherweise eine Instanz einer BookListPolicy oder ähnliches benötigt. Jede dieser Klassen hat unterschiedliche Lebensdauern (z. B. Dienste sind normalerweise Singletons, Komponenten sind normalerweise keine Singletons), und Angular muss alle diese Lebensdauern, die Erstellung der Komponenten und die Verkabelung der Abhängigkeiten verwalten.
  • CSS-Regeln mussten so geladen werden, dass sie nur für eine Teilmenge des DOM gelten (der Stil einer Komponente ist für diese Komponente lokal).

Möglicherweise ist zu beachten, dass Angular nicht dafür verantwortlich ist, wie Javascript-Dateien auf andere Javascript-Dateien verweisen (z import. B. das Schlüsselwort). Dafür sorgt Webpack.

Was macht der Compiler?

Nachdem Sie wissen, was Angular tut, können wir darüber sprechen, was der Compiler tut. Ich werde es vermeiden, zu technisch zu werden, hauptsächlich weil ich unwissend bin. In einem Abhängigkeits Einspritzanlage Allerdings haben Sie in der Regel Ihre Abhängigkeiten mit einer Art von Metadaten (zB wie funktioniert eine Klasse sagen wir zum Ausdruck bringen I can be injected, My lifetime is blahoder You can think of me as a Component type of instance). In Java hat Spring dies ursprünglich mit XML-Dateien getan. Java übernahm später Anmerkungen und sie sind die bevorzugte Methode zum Ausdrücken von Metadaten. C # verwendet Attribute, um Metadaten auszudrücken.

Javascript verfügt nicht über einen großartigen Mechanismus, um diese eingebauten Metadaten verfügbar zu machen. angle-js machte einen Versuch und es war nicht schlecht, aber es gab viele Regeln, die nicht einfach zu überprüfen waren und ein wenig verwirrend waren. Mit Angular gibt es zwei unterstützte Möglichkeiten, die Metadaten anzugeben. Sie können reines Javascript schreiben und die Metadaten manuell angeben, ähnlich wie bei angle-js. Befolgen Sie einfach die Regeln und schreiben Sie zusätzlichen Code für die Kesselplatte. Alternativ können Sie zu TypeScript wechseln, das zufällig Dekoratoren (diese @Symbole) enthält, mit denen Metadaten ausgedrückt werden.

Hier können wir also endlich zum Compiler gelangen. Die Aufgabe des Compilers besteht darin, diese Metadaten zu verwenden und das System der Werkstücke zu erstellen, das Ihre Anwendung ist. Sie konzentrieren sich auf alle Teile und alle Metadaten, und der Compiler erstellt eine große, miteinander verbundene Anwendung.

Wie macht der Compiler das?

Es gibt zwei Möglichkeiten, wie der Compiler arbeiten kann: Laufzeit und Vorausschau. Von hier an gehe ich davon aus, dass Sie TypeScript verwenden:

  • Laufzeit: Wenn der Typoskript-Compiler ausgeführt wird, werden alle Dekorationsinformationen in den Javascript-Code verschoben, der den dekorierten Klassen, Methoden und Feldern zugeordnet ist. In Ihrem index.htmlverweisen Sie auf Ihren, main.jsder die bootstrapMethode aufruft . Diese Methode wird Ihrem Top-Level-Modul übergeben.

Die Bootstrap-Methode startet den Laufzeit-Compiler und gibt ihm einen Verweis auf dieses Modul der obersten Ebene. Der Laufzeit-Compiler beginnt dann mit dem Crawlen des Moduls, aller Dienste, Komponenten usw., auf die dieses Modul verweist, sowie aller zugehörigen Metadaten und erstellt Ihre Anwendung.

  • AOT: Anstatt die gesamte Arbeit zur Laufzeit zu erledigen, hat Angular einen Mechanismus bereitgestellt, mit dem die meiste Arbeit zur Erstellungszeit erledigt werden kann. Dies geschieht fast immer mit einem Webpack-Plugin (dies muss eines der beliebtesten und am wenigsten bekannten npm-Pakete sein). Es wird ausgeführt, nachdem die Typoskript-Kompilierung ausgeführt wurde, sodass im Wesentlichen dieselbe Eingabe wie beim Laufzeit-Compiler angezeigt wird. Der AOT-Compiler erstellt Ihre Anwendung genau wie der Laufzeit-Compiler, speichert sie dann jedoch wieder in Javascript.

Der Vorteil hierbei ist nicht nur, dass Sie die für die Kompilierung selbst erforderliche CPU-Zeit sparen können, sondern auch, dass Sie die Größe Ihrer Anwendung reduzieren können.

Spezifische Antworten

Angular CLI Ruft zuerst den in Typescript => geschriebenen Angular Built-eingebauten Compiler auf und ruft dann den Typescript Transpiler => auf. Anschließend ruft das Webpack auf, um es zu bündeln und im Verzeichnis dist / zu speichern.

Nein. Angular CLI ruft Webpack auf (der eigentliche Dienst von Angular CLI ist das Konfigurieren von Webpack. Wenn Sie es ausführen ng build, ist es nicht viel mehr als ein Proxy zum Starten von Webpack). Webpack ruft zuerst den Typescript-Compiler und dann den Winkel-Compiler (unter der Annahme von AOT) auf und bündelt gleichzeitig Ihren Code.

Obwohl main.ts in der obigen Anweisung zur Erläuterung des Bootstrap-Prozesses verwendet wird, wird die Angular-App nicht mit Javascript-JS-Dateien gebootet oder gestartet?

Ich bin mir nicht ganz sicher, was Sie hier fragen. main.tswird in Javascript übertragen. Dieses Javascript enthält einen Aufruf, bootstrapder der Einstiegspunkt für Angular ist. Wenn bootstrapSie fertig sind, wird Ihre vollständige Angular-Anwendung ausgeführt.

Dieser Beitrag besagt, dass Angular zwei Compiler hat:

Compiler anzeigen

Modul-Compiler

Um ehrlich zu sein, werde ich hier nur Unwissenheit behaupten. Ich denke, auf unserer Ebene können wir uns alles nur als einen großen Compiler vorstellen.

Weiß jemand, wie alle Teile in der Tiefe zusammenpassen?

Ich hoffe, dass die oben genannten zufriedenstellend sind.

Don't @ Me: Angular bietet mehr als nur Abhängigkeitsinjektion

Sicher. Es übernimmt das Routing, das Erstellen von Ansichten, das Erkennen von Änderungen und viele andere Dinge. Der Compiler generiert tatsächlich Javascript für die Erstellung von Ansichten und die Erkennung von Änderungen. Ich habe gelogen, als ich sagte, es sei nur eine Abhängigkeitsinjektion. Die Abhängigkeitsinjektion ist jedoch das Kernstück und reicht aus, um den Rest der Antwort zu steuern.

Sollen wir es einen Compiler nennen?

Es führt wahrscheinlich viel Parsen und Lexieren durch und generiert definitiv viel Code, sodass Sie es aus diesem Grund als Compiler bezeichnen können.

Auf der anderen Seite wird Ihr Code nicht wirklich in eine andere Darstellung übersetzt. Stattdessen werden verschiedene Codeteile verwendet und zu Verbrauchsmaterialien eines größeren Systems verwoben. Der Bootstrap-Prozess nimmt dann (nach dem Kompilieren, falls erforderlich) diese Teile und steckt sie in den Angular-Kern.

Tempo
quelle
Vielen Dank für die ausführliche Antwort. Bevor ich Ihre Antwort akzeptiere, habe ich Zweifel an Ihrer Aussage The compiler does actually generate Javascript "für die Erstellung von Ansichten und die Erkennung von Änderungen". Es ist keine Lüge. Das macht der Compiler nicht? Und eckig macht die Abhängigkeitsinjektion.
Shaijut
1
Ja Entschuldigung. Die Lüge, auf die ich mich bezog, war „Im Kern ist der Dienst, den Angular bereitstellt, ein Mechanismus zur Abhängigkeitsinjektion“, denn während Angular dies tut, ist es nicht alles, was es tut, und nicht einmal alles, was der Compiler tut.
Pace
Wenn Angular als neue "Sprache" mit Funktionen wie Komponenten, Anweisungen, Diensten usw. abstrahiert wird. Es kann als Compiler bezeichnet werden. Complie Angular Sprache in rohen js und html.
Chris Bao
10

Lassen Sie mich von vorne beginnen.

In meiner Anwendung führe ich die Anwendung direkt aus Webpack.

Zum Erstellen und Ausführen der Anwendung verwenden wir den Befehl webpack --progress und webpack-dev-server --inline , in den package.jsonwie folgt geschrieben wurde

"scripts": {
    "serve": "webpack-dev-server --inline ",
    "build": "webpack --progress"

  }

Wenn wir den webpack --progressBefehl ausführen , beginnt die Lesedatei webpack.config.js, in der der Einstiegspunkt wie folgt gefunden wird.

module.exports = {
    devtool: 'source-map',
    entry: './src/main.ts',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
                exclude: [/\.(spec|e2e)\.ts$/]
            },
            /* Embed files. */
            {
                test: /\.(html|css)$/,
                loader: 'raw-loader',
                exclude: /\.async\.(html|css)$/
            },
            /* Async loading. */
            {
                test: /\.async\.(html|css)$/,
                loaders: ['file?name=[name].[hash].[ext]', 'extract']
            },
        ]
    },
    resolve: {
        extensions: ['.ts', '.js']
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}   

und dann liest es alle TypescriptDateien und Kompilierungen basierend auf den in der tsconfig.jsonDatei deklarierten Regeln und konvertiert sie dann in entsprechende .jsDateien und die Map-Datei.

Wenn es ohne Kompilierungsfehler ausgeführt wird, wird eine bundle.jsDatei mit Namen erstellt, wie im WebpackAusgabeabschnitt angegeben.

Lassen Sie mich nun erklären, warum wir Lader verwenden.

awesome-typescript-loader, angle2-template-loader Wir verwenden diesen Loader, um die TypescriptDatei auf der in der tsconfig.jsonDatei deklarierten Basis zu kompilieren, und angular2-template-loader sucht templateUrlund deklariert die styleUrlsMetadaten der Angular 2-Komponente und ersetzt die Pfade durch die entsprechenden Aussage erfordern.

resolve: {
        extensions: ['.ts', '.js']
    }

Wir verwenden den obigen Abschnitt zum Auflösen Webpack, um anzugeben , ob Typescripteine JavaScriptDatei konvertiert werden soll

plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]

Der Abschnitt Plugins wird zum Einfügen von Frameworks oder Dateien von Drittanbietern verwendet. In meinem Code verwende ich dies, um den index.htmlZielordner einzufügen.

 devtool: 'source-map',

Die obige Zeile wird verwendet, um die TypescriptDatei im Browser anzuzeigen und zu debuggen, die hauptsächlich für Entwicklercode verwendet wird.

 loader: 'raw-loader'

Das obige raw-loaderwird verwendet, um die .htmlund .css-Datei zu laden und zusammen mit den TypescriptDateien zu bündeln .

Am Ende, wenn wir webpack-dev-server --inline ausführen , wird ein eigener Server erstellt und die Anwendung als der in der web-pack.config.jsDatei angegebene Pfad gestartet , in dem der Zielordner und der Einstiegspunkt angegeben sind.

In Angular2 Einstiegspunkten der meisten Anwendungen wird main.tsbeispielsweise das ursprüngliche Bootstrap-Modul (app.module) erwähnt. Dieses Modul enthält vollständige Anwendungsinformationen wie alle Anweisungen, Dienste, Module, Komponenten und Routing-Implementierungen der gesamten Anwendung.

Hinweis: Viele Leute haben Zweifel, warum index.htmlsie die Anwendung nur starten sollten, obwohl sie nicht erwähnt haben, wo. Die Antwort lautet: Wenn Webpackder Befehl "Serve" ausgeführt wird, wird ein eigener Serve erstellt und standardmäßig geladen, index.htmlwenn Sie keine Standardseite erwähnt haben.

Ich hoffe, dass gegebene Informationen einigen Menschen helfen.

Arun
quelle
1
Schätzen Sie, dass Sie versucht haben zu erklären. Es wäre besser, wenn Sie es klarer nacheinander erklären könnten. Sie verwenden also keine Apps Angular CLIzum AngularErstellen und verwenden Webpackdirekt wie?
Shaijut
5

Wie baut Angular?

Die Angular CLIAufrufe geben Webpackbeim Aufrufen Webpackeiner .tsDatei diese an den TypeScriptCompiler weiter, der über einen Ausgangstransformator verfügt, der AngularVorlagen kompiliert

Die Build-Sequenz lautet also:

Angular CLI=> Webpack=> TypeScriptCompiler => TypeScriptCompiler ruft den AngularCompiler in der Kompilierungszeit auf.

Wie läuft Angular?

Angularbootstraps und läuft mit JavascriptDatei.

Tatsächlich ist der Bootstrap-Prozess zur Laufzeit und erfolgt vor dem Öffnen des Browsers. Dies bringt uns zu unserer nächsten Frage.

Wenn der Bootstrap-Prozess mit einer JavascriptDatei stattfindet, warum verwendet AngularDocs dann eine main.tsTypeScript-Datei, um den Bootstrap-Prozess zu erklären?

AngularDie Dokumente sprechen nur über die .tsDateien, da dies die Quelle ist.

Dies ist eine kurze Antwort. Schätzen Sie, ob jemand ausführlich antworten kann.

Credits gehen an @ Toxicable für die Beantwortung meiner Fragen im Chat.

Shaijut
quelle
2

Es könnte zu spät für diese Antwort sein, aber in letzter Zeit gab es ein wirklich gutes Gespräch über dieses Thema, das von einem Anfängersicht aus beginnt und ausführlich behandelt wird. Anstatt zu versuchen, Fehlinformationen in diesem Thread mit meinen Worten zusammenzufassen oder darauf hinzuweisen, werde ich nur das Video von Kara Erickson verlinken : Wie Angular funktioniert .

Sie ist die technische Leiterin des Angular-Frameworks und hält eine wirklich gute Präsentation zu:

  • Was sind die Hauptteile des Angular Frameworks?
  • Wie funktioniert der Compiler, was produziert er?
  • Was ist eine "Komponentendefinition"?
  • Was ist ein Anwendungs-Bootstrap, wie funktioniert er?
ForestG
quelle
1
Vielen Dank für Ihren Beitrag :), schätzen.
Shaijut
1

Wenn der Bootstrap-Prozess mit einer Javascript-Datei stattfindet, warum verwendet Angular Docs dann die TypeScript-Datei main.ts, um den Bootstrap-Prozess zu erklären?

Dies ist Teil der transformierten .js-Version von main.ts, die von ausgegeben wird und ng builddie noch nicht hässlich und minimiert ist. Wie erwarten Sie, dass ein Anfänger diesen Code versteht? sieht es nicht viel komplizierter aus?

Object(__WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__["a" /* platformBrowserDynamic */])().bootstrapModule(__WEBPACK_IMPORTED_MODULE_2__app_app_module__["a" /* AppModule */])
    .catch(function (err) { return console.log(err); });

und mit ng build --prod --build-optimizerdenen Sie Ihren Code hässlich machen und minimieren, um ihn zu optimieren, sind generierte Bundles kompakt und in einem unlesbaren Format.

webpackJsonp([1],{0:function(t,e,n){t.exports=n("cDNt")},"1j/l":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var r=Array.isArray||function(t){return t&&"number"==typeof t.length}},"2kLc

Während die Datei main.ts für Menschen lesbar und übersichtlich ist, verwendet die Datei angle.io main.ts, um den Bootstrap-Prozess der Winkelanwendung zu erläutern. Angular: Warum TypeScript? Abgesehen davon, wenn Sie ein Autor eines so großartigen Frameworks gewesen wären, welchen Ansatz hätten Sie verwendet, um Ihr Framework populär und benutzerfreundlich zu machen? Würden Sie sich nicht für eine klare und präzise Erklärung entscheiden, anstatt für eine komplizierte? Ich bin damit einverstanden, dass die Angular.io-Dokumentation keine ausführliche Erklärung enthält und nicht besonders gut ist, aber soweit ich gesehen habe, bemühen sie sich, sie besser zu machen.

Vikas
quelle
1

Angular 9+ verwendet AOT (Ahead of Time Compilation), dh es werden alle Bits verwendet, die in verschiedenen Dateien, dh Komponenten (.ts + .html + .css), Modulen (.ts), verstreut sind, und es wird ein vom Browser verständliches JavaScript erstellt, das zur Laufzeit heruntergeladen wird und vom Browser ausgeführt.

Vor Angular 9 war es JIT (Just in Time Compilation), bei dem der Code so kompiliert wurde, wie es vom Browser gefordert wurde.

Einzelheiten finden Sie unter: Angular AOT Documentaiton

ZAFMA
quelle