Search code examples
angularangular-compiler

Angular Compiler options


I'm looking explanation for some Angular Compiler options that are listed here:

  • useDebug - to switch on the debug
  • useJit - not clear (used only in one place)
  • defaultEncapsulation - to set default styles encapsulation
  • providers - not really clear (is it the same to ngModule decorator?)
  • missingTranslation - strategy what to do if translation key is missing
  • enableLegacyTemplate - to support template tag (that is already deprecated)

Solution

  • useJit

    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

    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.


    Providers

    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:

    enter image description here

    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

    enter image description here

    To simplify i omitted router-outlet injectors in the diagram.

    For more details see the design docs: