问题
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