【问题标题】:AOT and JIT with build-optimizer带有构建优化器的 AOT 和 JIT
【发布时间】:2017-10-14 15:08:19
【问题描述】:

我正在关注解决方案here 使用JitCompilerFactory 加载运行时编译器和自定义装饰器以保留组件和模块元数据。但是使用 angular-cli --build-optimizer 标志我得到:

错误错误:无法解析“解析器”的所有参数(?)。确保所有参数都用 Inject 修饰或具有有效的类型注释,并且“Parser”用 Injectable 修饰。

Here 是我的最小复制,运行ng serve --aot --build-optimizer。作为控制ng serve --aot 工作。

【问题讨论】:

    标签: angular angular-cli angular2-aot


    【解决方案1】:

    如果您使用选项 --build-optimizer,则 @angular-devkit/build-optimizer/webpack-loader 加载器将添加到 webpack 加载器列表中。

    @angular-devkit/build-optimizer/webpack-loader 从不属于platformWhitelist (source) 的类型中删除ctorParameters 定义:

    const platformWhitelist = [
      'PlatformRef_',
      'TestabilityRegistry',
      'Console',
      'BrowserPlatformLocation',
    ];
    

    我认为这是正确的行为。

    要解决这个问题,您可以在 JitCompilerFactory is created 之前手动初始化 ctorParameters

    import { 
      Compiler, ɵConsole as Console,
      Optional, Inject, Injector, 
      PACKAGE_ROOT_URL 
    } from '@angular/core';
    
    import {
      JitCompilerFactory,
      TemplateParser, CompilerConfig, CompileReflector,
      ElementSchemaRegistry, I18NHtmlParser, TEMPLATE_TRANSFORMS, DirectiveNormalizer,
      ResourceLoader, UrlResolver, HtmlParser, CompileMetadataResolver, NgModuleResolver,
      DirectiveResolver, SummaryResolver, PipeResolver, StaticSymbolCache, 
      ERROR_COLLECTOR_TOKEN,
      StyleCompiler, ViewCompiler, NgModuleCompiler, JitCompiler
    } from '@angular/compiler';
    
    import * as compiler from '@angular/compiler';
    
    export function compilerFactory() {
      restoreDecorators();
    
      return new JitCompilerFactory([{ useDebug: false, useJit: true }]).createCompiler();
    }
    
    function restoreDecorators() {
      (compiler.Parser as any).parameters = [compiler.Lexer];
      (TemplateParser as any).parameters = [
        CompilerConfig, CompileReflector, compiler.Parser, ElementSchemaRegistry,
        I18NHtmlParser, Console, [new Optional(), new Inject(TEMPLATE_TRANSFORMS)]
      ];
      (DirectiveNormalizer as any).parameters = [
        ResourceLoader, UrlResolver,
        HtmlParser, CompilerConfig
      ];
      (CompileMetadataResolver as any).parameters = [
        CompilerConfig, NgModuleResolver, DirectiveResolver, PipeResolver, SummaryResolver,
        ElementSchemaRegistry,
        DirectiveNormalizer, Console,
        [new Optional(), StaticSymbolCache],
        CompileReflector,
        [new Optional(), new Inject(ERROR_COLLECTOR_TOKEN)]
      ];
      (StyleCompiler as any).parameters = [UrlResolver];
      (ViewCompiler as any).parameters = [CompileReflector];
      (NgModuleCompiler as any).parameters = [CompileReflector];
      (NgModuleResolver as any).parameters = [CompileReflector];
      (DirectiveResolver as any).parameters = [CompileReflector];
      (PipeResolver as any).parameters = [CompileReflector];
    
      (JitCompiler as any).parameters = [
        Injector,
        CompileMetadataResolver,
        TemplateParser,
        StyleCompiler,
        ViewCompiler,
        NgModuleCompiler,
        SummaryResolver,
        CompilerConfig,
        Console
      ];
      (UrlResolver as any).parameters = [[new Inject(PACKAGE_ROOT_URL)]];
    }
    

    这似乎是有风险的,因为编译器会受到内部变化的影响。它适用于@angular/compiler@4.4.5,但可能不适用于其他版本。

    【讨论】:

    • 我不知道ctorParameters 是什么,但从上下文中我收集到这是 DI 知道向服务(和其他)构造函数注入什么的方式。如果您分叉github.com/angular/devkit 或提出功能请求,是否可以像将Compiler 添加到platformWhitelist 一样简单?
    • 我们不应该这样做。
    猜你喜欢
    • 2017-07-27
    • 2018-01-23
    • 2011-11-14
    • 2017-03-13
    • 2015-12-25
    • 2019-09-13
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多