Варианты углового компилятора
Я ищу объяснение некоторых параметров Angular Compiler, которые перечислены здесь:
- useDebug - включить отладку
- useJit - не ясно (используется только в одном месте)
- defaultEncapsulation - установить инкапсуляцию стилей по умолчанию
- провайдеры - не очень понятно (это то же самое для ngModule decorator?)
- missingTranslation - стратегия, что делать, если ключ перевода отсутствует
- enableLegacyTemplate - для поддержки
template
тег (это уже устарело)
1 ответ
useJit
используется ли кодоген или интерпретирующий режим.
Codegen является режимом по умолчанию, поэтому мы можем увидеть результат в инструментах разработки браузера. В этом режиме угловое преобразование всех операторов, собранных во время компиляции, в файлы с исполняемым кодом в памяти браузера.
Я знаю три места, где эта опция используется
Генерация фабрики модулей https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler.ts#L146
ng:///AppModule/module.ngfactory.js
Генерация фабрики компонентов https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler.ts#L282
ng:///AppModule/Component_Host.ngfactory.js
ng:///AppModule/Component.ngfactory.js
,styleUrls
генерация кода https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler.ts#L307ng:///css/0app/app.css.ngstyle.js
Интерпретативный режим означает, что angular будет работать как интерпретатор. Операторы, сгенерированные на предыдущих этапах (лексический анализ, анализ, семантический анализ, оптимизация), будут выполняться напрямую. Angular не переводит код в компоненты и модули модуля, как в режиме Codegen. Вместо угловых используются специальные обертки для фабрик, т.е.
function _declareFn(
varNames: string[], statements: o.Statement[], ctx: _ExecutionContext,
visitor: StatementInterpreter): Function {
return (...args: any[]) => _executeFunctionStatements(varNames, args, statements, ctx, visitor);
}
и затем он будет выполнять эти оболочки каждый раз, когда это необходимо. (Например, когда вы обрабатываете событие, когда работает angular updateDirectives
, updateRenderer
и т. д.) и каждый раз StatementVisitor
будет использоваться, чтобы пройти через все утверждения.
Первоначально интерпретирующий режим также используется для DART
https://github.com/angular/angular/commit/2b34c88b69af8b0031fdb7006327bb8260e23dda Но сейчас этот режим почти не используется AFAIK.
Провайдеры
Если у нас есть два провайдера с одинаковым токеном, второй провайдер "побеждает".
Так providers
опция - отличная возможность переопределить стандартное значение COMPILER_PROVIDERS
Например, мы можем
1) настроить DomElementSchema
2) использовать конкретные DirectiveResolver
переопределить шаблон
3) переопределить ResourceLoader
4) переопределить Parser
, TemplateParser
визуализировать работу компилятора
и так далее...
Мы не можем сделать то же самое с поставщиками NgModule, потому что компилятор использует выделенный инжектор (Инжектор JitCompiler на рисунке ниже) https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler_factory.ts#L115 и компиляция происходит https://github.com/angular/angular/blob/4.3.x/packages/core/src/application_ref.ts#L326-L329 до @NgModule
поставщики разрешены https://github.com/angular/angular/blob/4.3.x/packages/core/src/application_ref.ts#L297
Допустим, у нас есть приложение, как:
my-app
level1
level2
level3
Тогда алгоритм разрешения зависимостей будет выглядеть так:
Если мы используем отложенную загрузку для всех уровней https://plnkr.co/edit/AYExeiYRSQ4H8LiQEgKo?p=preview
my-app
router-outlet
level1
router-outlet
level2
router-outlet
level3
Это будет преобразовано в
Для упрощения я опустил router-outlet
форсунки на схеме.
Для более подробной информации смотрите документацию по дизайну: