I'm looking explanation for some Angular Compiler options that are listed here:
template
tag (that is already deprecated)is whether codegen or interpretative mode is used.
Codegen is default mode so we can see the output in browser development tools. In this mode angular transforms all statements collected during compilation to files with executable code in browser memory.
I know three places where this option is used
Module factory generation https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler.ts#L146
ng:///AppModule/module.ngfactory.js
Component factory generation 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
code generation https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler.ts#L307
ng:///css/0app/app.css.ngstyle.js
Interpretative mode means that angular will work like interpreter. Statements generated in previous steps(lexical analysis, parsing, semantic analysis, optimization) will be executed directly. Angular doesn't translate code to component and module ngfactories as it does in codegen mode. Instead angular uses special wrappers for factories i.e.
function _declareFn(
varNames: string[], statements: o.Statement[], ctx: _ExecutionContext,
visitor: StatementInterpreter): Function {
return (...args: any[]) => _executeFunctionStatements(varNames, args, statements, ctx, visitor);
}
and then it will execute these wrappers each time when it's necessary.(For example when you handle event, when angular is running updateDirectives
, updateRenderer
etc) And each time StatementVisitor
will be used to walk through all the statements.
Initially interpretative mode is also used for DART
https://github.com/angular/angular/commit/2b34c88b69af8b0031fdb7006327bb8260e23dda#diff-ba3d6dc88c6e1cef871391a7843a614eR167 But now this mode is almost not used AFAIK.
If we have two providers with the same token, the second provider "wins".
So providers
option is a great feature to override default COMPILER_PROVIDERS
For instance we can
1) customize DomElementSchema
2) use specific DirectiveResolver
to override template
3) override ResourceLoader
4) override Parser
, TemplateParser
to visualize the work of the compiler
and so on...
We can't do the same with NgModule providers because compiler uses dedicated injector(JitCompiler injector in the picture below) https://github.com/angular/angular/blob/4.3.x/packages/compiler/src/jit/compiler_factory.ts#L115 and the compilation happens https://github.com/angular/angular/blob/4.3.x/packages/core/src/application_ref.ts#L326-L329 before @NgModule
providers are resolved https://github.com/angular/angular/blob/4.3.x/packages/core/src/application_ref.ts#L297
Let's say we have app like:
my-app
level1
level2
level3
Then dependency resolution algorithm will look like:
If we use lazy loading for all levels https://plnkr.co/edit/AYExeiYRSQ4H8LiQEgKo?p=preview
my-app
router-outlet
level1
router-outlet
level2
router-outlet
level3
It will be transformed to
To simplify i omitted router-outlet
injectors in the diagram.
For more details see the design docs: