Jak buduje i działa Angular


85

Chcesz się tylko dowiedzieć, jak Angular tworzy i działa za kulisami?

Poniżej znajduje się to, co dotychczas zrozumiałem. Chcę wiedzieć, czy coś przegapiłem.

Jak buduje Angular

Po zakodowaniu naszych aplikacji Angular za pomocą TypeScript używamy polecenia Angular CLI do tworzenia aplikacji.

ng buildpolecenie kompiluje aplikację do katalogu wyjściowego, a artefakty kompilacji zostaną zapisane w dist/katalogu.

Proces wewnętrzny

1. Angular CLI uruchamia Webpack w celu zbudowania i spakowania całego kodu JavaScript i CSS.

2. Z kolei Webpack wywołuje programy ładujące TypeScript, które pobierają cały .tsplik w projekcie Angular, a następnie transponują je do JavaScript, czyli do .jspliku, który są w stanie zrozumieć przeglądarki.

W tym poście napisano, że Angular ma dwa kompilatory:

  • Wyświetl kompilator

  • Kompilator modułów

Pytania dotyczące kompilacji

Jaka jest kolejność wywoływania procesu kompilacji?

Angular CLI najpierw wywołuje wbudowany kompilator Angular napisany w TypeScript =>, a następnie wywołuje TypeScript Transpiler =>, a następnie wywołuje pakiet Webpack w celu spakowania i zapisania w dist/katalogu.

Jak działa Angular

Po zakończeniu kompilacji wszystkie komponenty, usługi, moduły itp. Naszej aplikacji są transponowane do JavaScript .jsplików używanych do uruchamiania aplikacji Angular w przeglądarce.

Oświadczenia w Angular Docs

  1. Podczas ładowania z AppComponentklasą (w main.ts), Angular szuka a <app-root>w index.html, znajduje, tworzy instancję AppComponent i renderuje ją wewnątrz <app-root>tagu.

  2. Angular tworzy, aktualizuje i niszczy komponenty, gdy użytkownik porusza się po aplikacji.

Pytania o biegi

Chociaż main.tsjest używany w powyższym oświadczeniu do wyjaśnienia procesu ładowania początkowego, czy aplikacja Angular nie jest ładowana lub uruchamiana przy użyciu .jsplików JavaScript ?

Czy wszystkie powyższe instrukcje nie są wykonywane w środowisku uruchomieniowym przy użyciu .jsplików JavaScript ?

Czy ktoś wie, jak dokładnie wszystkie części pasują do siebie?

Odpowiedzi:


91

(Kiedy mówię Angular, mam na myśli Angular 2+ i wyraźnie powiem angular-js, jeśli wspominam o kątowym 1).

Preludium: To zagmatwane

Angular, a prawdopodobnie dokładniej angular-cli połączyło ze sobą wiele popularnych narzędzi w Javascript, które są zaangażowane w proces kompilacji. Prowadzi to do pewnego zamieszania.

Aby pogłębić zamieszanie, termin ten compilebył często używany w angular-js w odniesieniu do procesu pobierania pseudo-html szablonu i przekształcania go w elementy DOM. To część tego, co robi kompilator, ale jedna z mniejszych części.

Przede wszystkim nie ma potrzeby używania TypeScript, angular-cli lub Webpack do uruchomienia Angulara. Odpowiedzieć na Twoje pytanie. Powinniśmy spojrzeć na proste pytanie: „Co to jest Angular?”

Angular: Co to robi?

Ta sekcja może być kontrowersyjna, zobaczymy. Zasadniczo usługa dostarczana przez Angular jest mechanizmem wstrzykiwania zależności, który działa w Javascript, HTML i CSS. Piszesz wszystkie małe fragmenty indywidualnie, aw każdym małym kawałku postępujesz zgodnie z zasadami Angulara dotyczącymi odwoływania się do innych elementów. Angular w jakiś sposób to wszystko łączy.

Aby być (nieco) bardziej szczegółowym:

  • Szablony pozwalają na połączenie kodu HTML ze składnikiem JavaScript. Umożliwia to wprowadzanie danych przez użytkownika w samym DOM (np. Kliknięcie przycisku) w celu przesłania do komponentu Javascript, a także pozwala zmiennym w komponencie Javascript na kontrolowanie struktury i wartości w DOM.
  • Klasy Javascript (w tym komponenty Javascript) muszą mieć dostęp do instancji innych klas Javascript, od których zależą (np. Klasyczne wstrzykiwanie zależności). BookListComponent wymaga wystąpienia BookListService, które może wymagać wystąpienia BookListPolicy lub czegoś podobnego. Każda z tych klas ma różne okresy istnienia (np. Usługi są zwykle singletonami, komponenty zwykle nie są singletonami), a Angular musi zarządzać wszystkimi tymi czasami istnienia, tworzeniem komponentów i okablowaniem zależności.
  • Reguły CSS musiały być ładowane w taki sposób, aby miały zastosowanie tylko do podzbioru DOM (styl komponentu jest lokalny dla tego komponentu).

Jedną z ważnych rzeczy do zapamiętania jest to, że Angular nie jest odpowiedzialny za to, w jaki sposób pliki Javascript odwołują się do innych plików Javascript (np. importSłowa kluczowego). Zadba o to Webpack.

Co robi kompilator?

Teraz, gdy wiesz, co robi Angular, możemy porozmawiać o tym, co robi kompilator. Uniknę zbytniego technicznego podejścia, głównie dlatego, że jestem ignorantem. Jednak w układzie wtrysku zależność zazwyczaj muszą wyrazić swoje zależnościami z pewnego rodzaju metadanych (np jak robi powiedzmy klasy I can be injected, My lifetime is blahlub You can think of me as a Component type of instance). W Javie Spring pierwotnie robił to z plikami XML. Później Java przyjęła adnotacje i stały się one preferowanym sposobem wyrażania metadanych. C # używa atrybutów do wyrażania metadanych.

Javascript nie ma świetnego mechanizmu ujawniania wbudowanych metadanych. angular-js podjął próbę i nie było to złe, ale było wiele reguł, których nie można było łatwo sprawdzić i które były nieco zagmatwane. W przypadku Angular istnieją dwa obsługiwane sposoby określania metadanych. Możesz napisać czysty Javascript i określić metadane ręcznie, trochę podobnie do angular-js i po prostu przestrzegać zasad i pisać dodatkowy kod boiler-platey. Alternatywnie możesz przełączyć się na TypeScript, który, tak jak to się dzieje, ma dekoratory (te @symbole), które są używane do wyrażania metadanych.

Więc tutaj możemy wreszcie dostać się do kompilatora. Zadaniem kompilatora jest pobranie tych metadanych i stworzenie systemu elementów roboczych, którym jest Twoja aplikacja. Skupiasz się na wszystkich elementach i wszystkich metadanych, a kompilator tworzy jedną dużą, połączoną aplikację.

Jak kompilator to robi?

Kompilator może działać na dwa sposoby: w czasie wykonywania i z wyprzedzeniem. Odtąd zakładam, że używasz TypeScript:

  • Środowisko uruchomieniowe: po uruchomieniu kompilatora maszynopisu pobiera wszystkie informacje dekoratora i umieszcza je w kodzie JavaScript dołączonym do ozdobionych klas, metod i pól. W swoim index.htmlodwołaniu się do tego, main.jsktóry wywołuje bootstrapmetodę. Ta metoda jest przekazywana do modułu najwyższego poziomu.

Metoda bootstrap uruchamia kompilator środowiska uruchomieniowego i podaje mu odniesienie do tego modułu najwyższego poziomu. Następnie kompilator środowiska uruchomieniowego zaczyna przeszukiwać ten moduł, wszystkie usługi, komponenty itp., Do których odwołuje się ten moduł, oraz wszystkie powiązane metadane, a następnie tworzy aplikację.

  • AOT: Zamiast wykonywać całą pracę w czasie wykonywania, Angular dostarczył mechanizm do wykonywania większości pracy w czasie kompilacji. Prawie zawsze odbywa się to za pomocą wtyczki webpack (musi to być jeden z najpopularniejszych, ale najmniej znanych pakietów npm). Uruchamia się po uruchomieniu kompilacji maszynopisu, więc zasadniczo widzi te same dane wejściowe, co kompilator środowiska uruchomieniowego. Kompilator AOT tworzy aplikację tak samo jak kompilator środowiska wykonawczego, ale następnie zapisuje ją z powrotem w JavaScript.

Zaletą jest nie tylko to, że można zaoszczędzić czas procesora wymagany do samej kompilacji, ale także pozwala zmniejszyć rozmiar aplikacji.

Konkretne odpowiedzi

Angular CLI Najpierw wywołuje wbudowany kompilator angular napisany w Typescript =>, a następnie wywołuje Typescript Transpiler =>, a następnie wywołuje pakiet Webpack w celu spakowania i przechowywania w katalogu dist /.

Nie. Angular CLI wywołuje Webpack (prawdziwą usługą Angular CLI jest konfigurowanie webpacka. Po uruchomieniu ng buildnie jest to nic innego jak proxy do uruchamiania Webpacka). Webpack najpierw wywołuje kompilator Typescript, a następnie kompilator kątowy (zakładając AOT), a wszystko to jednocześnie pakując kod.

Chociaż main.ts jest używany w powyższym oświadczeniu do wyjaśnienia procesu ładowania początkowego, czy aplikacja angular nie jest uruchamiana lub uruchamiana przy użyciu plików Javascript .js?

Nie jestem do końca pewien, o co tutaj pytasz. main.tszostaną przesłane do Javascript. Ten JavaScript będzie zawierał wywołanie, bootstrapktóre jest punktem wejścia do Angular. Po bootstrapzakończeniu będziesz mieć uruchomioną pełną aplikację Angular.

W tym poście napisano, że Angular ma dwa kompilatory:

Wyświetl kompilator

Kompilator modułów

Szczerze mówiąc, powiem tu tylko o ignorancji. Myślę, że na naszym poziomie możemy po prostu myśleć o tym wszystkim jako o jednym dużym kompilatorze.

Czy ktoś wie, jak dokładnie wszystkie części pasują do siebie?

Mam nadzieję, że powyższe zadowoliło.

Don't @ Me: Angular to coś więcej niż wstrzyknięcie zależności

Pewnie. Obsługuje routing, budowanie widoku, wykrywanie zmian i wiele innych rzeczy. Kompilator faktycznie generuje JavaScript do tworzenia widoków i wykrywania zmian. Skłamałem, mówiąc, że to tylko zastrzyk uzależnienia. Jednak zastrzyk zależności jest sednem i wystarczający, aby napędzać resztę odpowiedzi.

Czy powinniśmy nazywać to kompilatorem?

Prawdopodobnie wykonuje dużo analizowania i leksowania i na pewno generuje w rezultacie dużo kodu, więc z tego powodu można nazwać go kompilatorem.

Z drugiej strony, tak naprawdę nie tłumaczy twojego kodu tylko na inną reprezentację. Zamiast tego polega na pobieraniu kilku różnych fragmentów kodu i wplataniu ich w zużywalne elementy większego systemu. Następnie proces ładowania początkowego (po skompilowaniu, jeśli to konieczne) pobiera te elementy i podłącza je do rdzenia Angulara.


Dziękuję za szczegółową odpowiedź. Zanim przyjmuję twoją odpowiedź, mam wątpliwości co do twojego The compiler does actually generate Javascript oświadczenia, aby zobaczyć budowanie i wykrywanie zmian .` To nie jest kłamstwo. Tym nie jest kompilator? A angular robi zastrzyk zależności.
Shaiju T

1
Tak, przepraszam. kłamstwo, o którym mówiłem, brzmiało: „W istocie usługa, którą zapewnia Angular, jest mechanizmem wstrzykiwania zależności”, ponieważ chociaż Angular to robi, nie jest to wszystko, co robi, a nawet nie wszystko, co robi kompilator.
Tempo

Jeśli Angular jest zawstydzony jako nowy „język” z funkcjami takimi jak komponenty, dyrektywy, usługi i tak dalej. Można go nazwać kompilatorem. Dopasuj język Angular do surowego js i html.
Chris Bao

10

Zacznę od początku.

W mojej aplikacji uruchamiam aplikację bezpośrednio z Webpack.

Do zbudowania i uruchomienia aplikacji używamy komendy webpack --progress i webpack -dev-server --inline, która została napisana package.jsonjak poniżej

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

  }

Kiedy uruchamiamy webpack --progresspolecenie, rozpoczyna się odczyt webpack.config.jspliku, w którym znajduje punkt wejścia, jak poniżej.

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'
        })
    ]
}   

a następnie odczytuje cały Typescriptplik i kompiluje na podstawie reguł zadeklarowanych w tsconfig.jsonpliku, a następnie konwertuje go na odpowiednie .jspliki i plik mapy.

Jeśli działa bez błędu kompilacji, utworzy bundle.jsplik o nazwach takich jak zadeklarowaliśmy w Webpacksekcji wyjściowej.

Teraz wyjaśnię, dlaczego używamy ładowarek.

awesome-typescript-loader, angular2-template-loader Używamy tych ładujących do kompilacji Typescriptpliku na podstawie zadeklarowanej w tsconfig.jsonpliku, a program ładujący angular2-template-loader wyszukuje templateUrli styleUrlsdeklaruje wewnątrz metadanych komponentu Angular 2 i zastępuje ścieżki odpowiednimi wymagają oświadczenia.

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

Używamy powyższej sekcji rozwiązywania, aby powiedzieć, Webpackaby przekonwertować Typescriptdo JavaScriptpliku

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

Sekcja wtyczek służy do wstrzykiwania frameworka lub pliku innej firmy. W moim kodzie używam tego do wstrzyknięcia index.htmlfolderu docelowego.

 devtool: 'source-map',

Powyższy wiersz służy do wyświetlenia Typescriptpliku w przeglądarce i debugowania go głównie w kodzie programisty.

 loader: 'raw-loader'

Powyższy raw-loadersłuży do załadowania .htmli .cssplik, a następnie zepnij je wraz z Typescriptplikami.

Na koniec, gdy uruchomimy webpack-dev-server --inline , utworzy on własny serwer i uruchomi aplikację zgodnie ze ścieżką wymienioną w web-pack.config.jspliku, w którym wymieniliśmy folder docelowy i punkt wejścia.

W Angular2 punkcie wejścia większości aplikacji jest miejsce, w main.tsktórym wspominamy o początkowym module bootstrap, na przykład (app.module) ten moduł zawiera pełne informacje o aplikacji, takie jak wszystkie dyrektywy, usługi, moduły, komponenty i implementacja routingu całej aplikacji.

Uwaga: Wiele osób ma wątpliwości, po co index.htmltylko uruchamiać aplikację, mimo że nie wspomnieli o tym, gdzie. Odpowiedzią jest to, że po Webpackuruchomieniu polecenia serv tworzy własny serwis i domyślnie ładuje się, index.htmljeśli nie podałeś żadnej domyślnej strony.

Mam nadzieję, że podane informacje pomogą niektórym ludziom.


1
Doceń, że próbowałeś wyjaśnić. Byłoby lepiej, gdybyś mógł wyjaśnić w bardziej przejrzysty, sekwencyjny sposób. Więc nie używasz Angular CLIdo tworzenia Angularaplikacji i używasz Webpackbezpośrednio w jaki sposób?
Shaiju T

5

Jak buduje się Angular?

Te Angular CLIrozmowy Webpack, gdy Webpacknatrafi .tsplik przekazaniem go wyłączyć do TypeScriptkompilatora, który ma transformator wyjściowy, który kompiluje Angularszablony

Zatem sekwencja budowania jest następująca:

Angular CLI=> Webpack=> TypeScriptCompiler => TypeScriptKompilator wywołuje Angularkompilator w czasie kompilacji.

Jak działa Angular?

Angularładuje się i uruchamia przy użyciu Javascriptpliku.

W rzeczywistości proces ładowania początkowego jest procesem uruchomieniowym i ma miejsce przed otwarciem przeglądarki. To prowadzi nas do następnego pytania.

Jeśli więc proces ładowania początkowego ma miejsce z Javascriptplikiem, to dlaczego AngularDocs używa main.tspliku TypeScript do wyjaśnienia procesu ładowania początkowego?

AngularDokumenty mówią tylko o .tsplikach, ponieważ są one źródłem.

To jest krótka odpowiedź. Doceń, jeśli ktoś może odpowiedzieć szczegółowo.

Kredyty trafiają do @ Toxicable za odpowiedzi na moje pytania na czacie.


2

Może się spóźnić na tę odpowiedź, ale ostatnio odbyła się naprawdę dobra rozmowa na ten temat, która zaczyna się od początkującego punktu widzenia i jest dogłębna. Zamiast próbować podsumować lub wskazać dezinformację w tym wątku moimi słowami, po prostu połączę wideo autorstwa Kary Erickson: Jak działa Angular .

Jest liderem technicznym frameworku Angular i robi naprawdę dobrą prezentację na temat:

  • jakie są główne części frameworka Angular
  • jak działa kompilator, co produkuje
  • co to jest „definicja komponentu”
  • Co to jest bootstrap aplikacji, jak to działa

1
Dziękuję za wkład :), Doceniam.
Shaiju T

1

Jeśli więc proces ładowania początkowego odbywa się z plikiem Javascript, to dlaczego Angular Docs używa pliku Main.ts TypeScript do wyjaśnienia procesu ładowania początkowego?

Jest to część przekształconej wersji main.ts .js, ng buildktóra jest emitowana przez, która nie została jeszcze zdublowana i zminimalizowana. Jak można oczekiwać, że początkujący zrozumie ten kod? czy to nie wygląda na zbyt skomplikowane?

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); });

i za pomocą ng build --prod --build-optimizerktórego uglikuje i minimalizuje kod w celu jego optymalizacji, generowane pakiety są kompaktowe i są w formacie nieczytelnym bitowo.

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

podczas gdy plik main.ts jest czytelny dla człowieka i przejrzysty, dlatego angular.io używa main.ts do wyjaśnienia procesu ładowania aplikacji kątowej. Angular: Dlaczego TypeScript? poza tym, gdybyś był autorem tak świetnego frameworka, jakie podejście byś zastosował, aby uczynić swój framework popularnym i przyjaznym dla użytkownika? czy nie wybrałbyś raczej jasnego i zwięzłego wyjaśnienia niż skomplikowanego? Zgadzam się, że w dokumentacji angular.io brakuje dogłębnego wyjaśnienia i nie jest ona zbyt dobra, ale z tego, co widziałem, bardzo się starają, aby było lepiej.


1

Angular 9+ używa AOT (Ahead of Time Compilation), co oznacza, że ​​pobiera wszystkie bity rozproszone w różnych plikach, tj. Komponent (.ts + .html + .css), moduły (.ts) i konstruuje zrozumiały dla przeglądarki JavaScript, który jest pobierany w czasie wykonywania i wykonywane przez przeglądarkę.

Przed Angular 9 był to JIT (Just in time Compilation), w którym kod był kompilowany zgodnie z wymaganiami przeglądarki.

Aby uzyskać szczegółowe informacje, patrz: Angular AOT Documentaiton

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.