AOT and JIT with build-optimizer

别来无恙 提交于 2019-12-11 03:35:45

问题


I am following the solution here of using the JitCompilerFactory to load the runtime compiler and custom decorators to preserve the component and module metadata. But with the angular-cli --build-optimizer flag I get:

ERROR Error: Cannot resolve all parameters for 'Parser'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'Parser' is decorated with Injectable.

Here is my minimal reproduction, run ng serve --aot --build-optimizer. As a control ng serve --aot works.


回答1:


If you use option --build-optimizer then @angular-devkit/build-optimizer/webpack-loader loader is added to webpack loaders list.

@angular-devkit/build-optimizer/webpack-loader removes ctorParameters definitions from types that is not part of platformWhitelist (source):

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

I think that's correct behavior.

To work around it you could initialize ctorParameters manually before JitCompilerFactory is created:

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

And it seems to be risky as compiler is subject to internal changes. It works for @angular/compiler@4.4.5 but may not work for other releases.



来源:https://stackoverflow.com/questions/46737688/aot-and-jit-with-build-optimizer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!