Як Angular будує та працює


84

Просто хочете дізнатися, як Angular будує та працює за кадром?

Нижче наведено те, що я досі розумів. Хочу знати, якщо я щось пропустив.

Як будується Angular

Після кодування наших програм Angular за допомогою TypeScript, ми використовуємо команду Angular CLI для створення програми.

ng buildкоманда компілює додаток у вихідний каталог, і артефакти збірки зберігатимуться в dist/каталозі.

Внутрішній процес

1. Angular CLI запускає Webpack для побудови та об'єднання всіх кодів JavaScript та CSS.

2. У свою чергу, Webpack викликає завантажувачі TypeScript, які отримують усі .tsфайли в проекті Angular, а потім транспілюють їх до JavaScript, тобто до .jsфайлу, який браузери можуть зрозуміти.

У цій публікації сказано, що Angular має два компілятори:

  • Переглянути компілятор

  • Компілятор модулів

Запитання щодо збірок

Яка послідовність виклику процесу збірки?

Angular CLI спочатку викликає вбудований компілятор Angular, написаний на TypeScript =>, потім викликає TypeScript Transpiler =>, а потім викликає Webpack для зв’язування та зберігання в dist/каталозі.

Як працює Angular

Після завершення збірки всі компоненти, служби, модулі тощо нашої програми перекладаються у JavaScript .jsфайли, які використовуються для запуску програми Angular у браузері.

Заяви в Angular Docs

  1. Коли ви завантажуєтеся з AppComponentкласом (у main.ts), Angular шукає a <app-root>у index.html, знаходить його, створює екземпляр екземпляра AppComponent і відображає його всередині <app-root>тегу.

  2. Angular створює, оновлює та знищує компоненти під час переміщення користувача через додаток.

Питання про пробіжки

Незважаючи на те main.ts, що використовується у заяві вище для пояснення процесу завантаження, хіба програма Angular не завантажується або не запускається за допомогою .jsфайлів JavaScript ?

Чи не всі вищезазначені твердження виконуються під час виконання за допомогою .jsфайлів JavaScript ?

Хтось знає, як усі частини поєднуються по глибині?

Відповіді:


89

(Коли я кажу Angular, я маю на увазі Angular 2+ і явно скажу angular-js, якщо я згадую angular 1).

Прелюдія: Це бентежить

Кутові та, мабуть, точніше angular-cli об’єднали низку популярних інструментів у Javascript, які беруть участь у процесі збірки. Це призводить до невеликої плутанини.

Для подальшої плутанини цей термін compileчасто використовувався в angular-js для позначення процесу взяття псевдо-html шаблону та перетворення його в елементи DOM. Це частина того, що робить компілятор, але одна з менших частин.

Перш за все, для запуску Angular немає необхідності використовувати TypeScript, angular-cli або Webpack. Щоб відповісти на ваше запитання. Ми повинні розглянути просте запитання: "Що таке Angular?"

Angular: Що це робить?

Цей розділ може бути суперечливим, ми побачимо. По суті, послуга, яку надає Angular, - це механізм введення залежностей, який працює в Javascript, HTML та CSS. Ви пишете всі дрібні шматочки окремо, і в кожному маленькому шматочку ви дотримуєтесь правил Angular щодо посилання на інші шматочки. Тоді Angular переплете це все якось.

Щоб бути (трохи) більш конкретним:

  • Шаблони дозволяють підключати HTML до компоненту Javascript. Це дозволяє користувачеві вводити дані в саму DOM (наприклад, натисканням кнопки) для подачі в компонент Javascript, а також дозволяє змінним в компоненті Javascript контролювати структуру та значення в DOM.
  • Класи Javascript (включаючи компоненти Javascript) повинні мати доступ до екземплярів інших класів Javascript, від яких вони залежать (наприклад, класичне введення залежностей). BookListComponent потребує екземпляра BookListService, який може потребувати екземпляра BookListPolicy або щось подібне. Кожен із цих класів має різний час життя (наприклад, служби, як правило, одиничні, компоненти, як правило, не одиночні), і Angular повинен керувати всіма цими життями, створенням компонентів та підключенням залежностей.
  • Правила CSS потрібно було завантажувати таким чином, щоб вони застосовувались лише до підмножини DOM (стиль компонента є локальним для цього компонента).

Важливо зазначити, що Angular не несе відповідальності за те, як файли Javascript посилаються на інші файли Javascript (наприклад, importключове слово). Про це піклується Webpack.

Що робить компілятор?

Тепер, коли ви знаєте, що робить Angular, ми можемо говорити про те, що робить компілятор. Я уникатиму надто технічного характеру, головним чином тому, що я невігла. Однак, в системі впорскування залежностей ви зазвичай повинні висловлювати свої залежності з якою - то метаданих (наприклад , як робить клас скажімо I can be injected, My lifetime is blahабо You can think of me as a Component type of instance). На Java, Spring спочатку робив це з файлами XML. Пізніше Java прийняла анотації, і вони стали найкращим способом вираження метаданих. C # використовує атрибути для вираження метаданих.

Javascript не має чудового механізму викриття цих метаданих. angular-js зробив спробу, і це було непогано, але було багато правил, які неможливо було легко перевірити і трохи заплутали. У Angular існує два підтримуваних способи вказівки метаданих. Ви можете писати чистий Javascript і вказувати метадані вручну, дещо схоже на angular-js, і просто продовжувати дотримуватися правил і писати додатковий кодовий код. Крім того, ви можете перейти на TypeScript, який, як це трапляється, має декоратори (ті @символи), які використовуються для вираження метаданих.

Отже, ось де ми нарешті можемо дістатись до компілятора. Завдання компілятора полягає в тому, щоб взяти ці метадані та створити систему робочих частин, яка є вашим додатком. Ви зосереджуєтесь на всіх частинах та на всіх метаданих, і компілятор створює один великий взаємопов’язаний додаток.

Як це робить компілятор?

Існує два способи роботи компілятора, час виконання та випередження. Відтепер я вважаю, що ви використовуєте TypeScript:

  • Час роботи: під час запуску компілятора машинопису він бере всю інформацію про декоратор і вписує його в код Javascript, прикріплений до оформлених класів, методів та полів. У вашому index.htmlпосиланні на ваш, main.jsякий викликає bootstrapметод. Цей метод передається модулю верхнього рівня.

Метод bootstrap запускає компілятор середовища виконання і дає йому посилання на цей модуль верхнього рівня. Потім компілятор середовища виконання починає сканувати цей модуль, усі служби, компоненти тощо, на які посилається цей модуль, і всі пов’язані з ним метадані, та створює вашу програму.

  • AOT: Замість того, щоб виконувати всю роботу під час виконання, Angular забезпечив механізм виконання більшості робіт під час збірки. Це майже завжди робиться за допомогою плагіна webpack (це повинен бути один з найпопулярніших, але найменш відомих пакетів npm). Він запускається після запуску компіляції TypeScript, тому він бачить по суті той самий вхід, що і компілятор середовища виконання. Компілятор AOT створює вашу програму так само, як і компілятор середовища виконання, але потім зберігає її назад у Javascript.

Перевага тут полягає не тільки в тому, що ви можете заощадити час процесора, необхідний для самої компіляції, але це також дозволяє зменшити розмір вашої програми.

Конкретні відповіді

Angular CLI Спочатку викликає вбудований компілятор angular, написаний у Typescript =>, потім викликає Typescript Transpiler =>, а потім викликає Webpack для зв’язування та зберігання в каталозі dist /.

Ні. Angular CLI викликає Webpack (справжньою службою Angular CLI є налаштування webpack. При запуску ng buildце не набагато більше, ніж проксі для запуску Webpack). Спочатку Webpack викликає компілятор Typescript, а потім кутовий компілятор (припускаючи AOT), одночасно поєднуючи ваш код.

Незважаючи на те, що main.ts використовується у вищезазначеному викладі для пояснення процесу завантаження, чи не завантажується кутова програма або не запускається за допомогою файлів .js Javascript?

Я не зовсім впевнений, що ви тут питаєте. main.tsбуде перенесено в Javascript. Цей Javascript міститиме виклик, bootstrapякий є точкою входу до Angular. Після bootstrapзакінчення у вас буде запущена повна програма Angular.

У цій публікації сказано, що Angular має два компілятори:

Переглянути компілятор

Компілятор модулів

Чесно кажучи, я просто збираюся стверджувати тут незнання. Я думаю, що на нашому рівні ми можемо просто сприймати все це як один великий компілятор.

Хтось знає, як усі частини поєднуються по глибині?

Сподіваюсь, вищезазначене це задовольнило.

Don't @ Me: Angular робить більше, ніж введення залежностей

Звичайно. Він робить маршрутизацію, побудову перегляду, виявлення змін та всілякі інші речі. Компілятор насправді генерує Javascript для побудови подання та виявлення змін. Я збрехав, коли сказав, що це просто ін'єкція залежності. Однак введення залежності є основним і достатньою, щоб забезпечити решту відповідей.

Чи слід називати його компілятором?

Ймовірно, це робить багато аналізу та лексики і, безумовно, генерує багато коду в результаті, тому ви можете назвати його компілятором з цієї причини.

З іншого боку, це насправді не переклад вашого коду просто в інше представлення. Натомість він бере купу різних фрагментів коду і переплітає їх у витратні частини більшої системи. Потім процес завантаження (після компіляції, якщо це необхідно) бере ці фрагменти та підключає їх до Angular core.


Дякую за детальну відповідь. Перш ніж прийняти вашу відповідь, я сумніваюся у The compiler does actually generate Javascript у вашій заяві для побудови вигляду та виявлення змін. `Це не брехня. Це те, що робить компілятор, чи не так? І кутова робить введення залежності.
shaijut

1
Так, вибачте. брехня, про яку я мав на увазі, була “По суті, послуга, яку надає Angular, є механізмом введення залежностей”, оскільки, хоча Angular робить це, це не все, що робить, і навіть не весь компілятор.
Темп

Якщо Angular абстрагується як нова "мова" з такими функціями, як компоненти, директиви, служби тощо. Його можна назвати компілятором. Мова Complie Angular перетворюється на raw js та html.
Кріс Бао

10

Дозвольте мені почати спочатку.

У моїй програмі я безпосередньо запускаю програму з Webpack.

Для побудови та запуску програми ми використовуємо webpack --progress та webpack-dev-server --inline команда, про яку було записано, package.jsonяк показано нижче

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

  }

Коли ми запускаємо webpack --progressкоманду, він запускає webpack.config.jsфайл читання, де він знаходить точку входу, як показано нижче.

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

а потім читає весь Typescriptфайл і компілює на основі правил, оголошених у tsconfig.jsonфайлі, а потім перетворює його у відповідні .jsфайли і це файл карти.

Якщо він працює без помилок компіляції, він створить bundle.jsфайл з іменами, як ми оголосили в розділі Webpackвиводу.

А тепер дозвольте пояснити, чому ми використовуємо навантажувачі.

страхітливий-машинопис-навантажувач, angular2-шаблон-навантажувач Ми використовуємо ці завантажувач для компіляції Typescriptфайлу на засадах оголошеного в tsconfig.jsonпошуках файлів і angular2-шаблон-навантажувачі templateUrlта styleUrlsвнутрішньої декларації про кутових 2 компоненті метаданих і замінюють шляху з відповідним вимагати заяви.

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

Ми використовуємо наведений вище розділ вирішення, щоб сказати Webpackперетворити Typescriptу JavaScriptфайл

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

Розділ плагінів використовується для введення сторонніх середовищ або файлів. У своєму коді я використовую це для введення index.htmlцільової папки.

 devtool: 'source-map',

Наведений вище рядок використовується для перегляду Typescriptфайлу в браузері та налагодження, який в основному використовується для коду розробника.

 loader: 'raw-loader'

Вище raw-loaderвикористовується для завантаження .htmlі .cssфайл і пов'язати їх разом з Typescriptфайлами.

Врешті-решт, коли ми запускаємо webpack-dev-server --inline, він створить власний сервер і завантажить програму як шлях, згаданий у web-pack.config.jsфайлі, де ми згадали цільову папку та точку входу.

У Angular2 точці входу більшості програм, main.tsде ми згадуємо початковий модуль завантаження, наприклад (app.module), цей модуль містить повну інформацію про програму, таку як усі директиви, служби, модулі, компоненти та реалізація маршрутизації всього додатка.

Примітка: Багато людей сумніваються, що навіщо index.htmlтільки завантажувати програму, хоча вони ніде не згадали. Відповідь полягає в тому, що коли Webpackкоманда serve запускає, вона створює власну службу і за замовчуванням завантажується, index.htmlякщо ви не згадали жодної сторінки за замовчуванням.

Я сподіваюся, що надана інформація допоможе комусь.


1
Цінуйте, що ви намагалися пояснити. Було б краще, якби ви могли пояснити більш чітко послідовно. Тож Ви не використовуєте Angular CLIдля створення Angularдодатків, а Webpackяк безпосередньо?
shaijut

5

Як будує Angular?

У Angular CLIвикликах Webpack, коли Webpackпотрапить в .tsфайл , він передає його в TypeScriptкомпілятор , який має вихідний трансформатор , який компілює Angularшаблони

Отже, послідовність побудови така:

Angular CLI=> Webpack=> TypeScriptКомпілятор => TypeScriptКомпілятор викликає Angularкомпілятор під час компіляції.

Як працює Angular?

Angularbootstraps і запускається за допомогою Javascriptфайлу.

Фактично процес завантаження запуску виконується і відбувається до відкриття браузера. Це переходить до нашого наступного питання.

Отже, якщо процес завантаження відбувається з Javascriptфайлом, то чому AngularDocs використовує main.tsфайл TypeScript для пояснення процесу завантаження?

AngularДокументи просто говорять про .tsфайли, оскільки це джерело.

Це коротка відповідь. Оцініть, якщо хтось може дати глибоку відповідь.

Кредити надходять на @ Toxicable за відповіді на мої запитання в чаті.


2

Можливо, запізнився на цю відповідь, але нещодавно було дуже хороших розмов на цю тему, яка починається з точки зору початківців і заглиблюється. Замість того, щоб намагатися узагальнити або вказати на дезінформацію в цій темі своїми словами, я просто зв’яжу відео Відео Кара Еріксон: Як працює Angular .

Вона є технічним лідером у Angular framework і робить справді гарну презентацію на тему:

  • які основні частини Angular framework
  • як працює компілятор, що він виробляє
  • що таке "визначення компонента"
  • Що таке завантажувальний файл програми, як він працює

1
Дякуємо за внесок :), ціную.
shaijut

1

Тож якщо процес завантаження відбувається з файлом Javascript, чому Angular Docs використовує файл main.ts TypeScript для пояснення процесу завантаження?

Це частина трансформованої .js-версії main.ts, що випускається, ng buildяка ще не забруднена та зменшена. Як ви очікуєте, що новачок зрозуміє цей код? чи не виглядає це набагато складніше?

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

і за допомогою ng build --prod --build-optimizerякого ваш код згладжується та мініфікується для його оптимізації, згенеровані пакети є компактними та мають нерозбірливий формат.

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

тоді як файл main.ts зручний для читання та зрозумілий, тому angular.io використовує main.ts для пояснення процесу завантаження кутового додатка. Angular: чому TypeScript? крім цього, якби ви були автором такого чудового фреймворку, який підхід ви застосували б для того, щоб зробити ваш фреймворк популярним та зручним для користувачів? чи не пішли б ви на чітке та стисле пояснення, а не на складне? Я згоден з тим, що у документації angular.io бракує глибоких пояснень, і це не дуже добре, але, наскільки я вже бачив, вони прагнуть зробити це краще.


1

Angular 9+ використовує AOT (Ahead of Time Compilation), що означає, що він бере всі біти, розкидані у різних файлах, тобто компонент (.ts + .html + .css), модулі (.ts) і створює зрозумілий для браузера JavaScript, який під час виконання завантажується і виконується браузером.

До Angular 9 це був JIT (Just in time Compilation), де код компілювався так, як того вимагав браузер.

Детальніше див .: Документація про кутові AOT

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.