介绍
我正在尝试创建自己的自定义平台以在 Angular 7 中使用。基本思想是提供一个用于渲染到终端的平台。这是我目前所在的位置:
编码
平台控制台/控制台渲染器.ts
(或多或少基于 Victor Savkin 非常出色的教程:Angular Renderers 实验)
import { Renderer2, RendererStyleFlags2, NgModule, RootRenderer, RendererFactory2, RendererType2, NgZone, APP_INITIALIZER, Injectable } from '@angular/core';
export type ConsoleNode = ConsoleElement | ConsoleText;
export class ConsoleRenderer extends Renderer2 {
// extremely basic renderer tree management in here -- not important right now
}
@Injectable()
export class ConsoleRendererFactory implements RendererFactory2 {
public defaultRenderer = new ConsoleRenderer();
createRenderer(hostElement: ConsoleNode, type: RendererType2): Renderer2 {
return this.defaultRenderer;
}
}
export function setUpRenderFlushing(zone: NgZone, rendererFactory: ConsoleRendererFactory) {
return () => {
zone.onStable.subscribe(() => {
console.group('--');
console.log(rendererFactory.defaultRenderer.root);
console.log(JSON.stringify(rendererFactory.defaultRenderer.root, null, 2));
console.groupEnd();
});
};
}
平台控制台/console.ts
(松散地基于Angular 提供的平台)
/* imports, etc */
export const PLATFORM_CONSOLE_ID = 'console';
export const INTERNAL_CONSOLE_PLATFORM_PROVIDERS: StaticProvider[] = [
{ provide: PLATFORM_ID, useValue: PLATFORM_CONSOLE_ID },
{provide: COMPILER_OPTIONS, useValue: {}, multi: true},
{provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
{ provide: DOCUMENT, useFactory: getDocument, deps: [] }
]
export const platformConsole: (extraProviders?: StaticProvider[]) => PlatformRef =
createPlatformFactory(platformCore, 'console', INTERNAL_CONSOLE_PLATFORM_PROVIDERS);
export function getDocument(): any {
return document;
}
export function getErrorHandler(): ErrorHandler {
return new ErrorHandler();
}
export const CONSOLE_MODULE_PROVIDERS: StaticProvider[] = [
{ provide: APP_ROOT, useValue: true },
{ provide: ErrorHandler, useFactory: getErrorHandler, deps: [] },
{ provide: RendererFactory2, useClass: ConsoleRendererFactory, deps: [] },
{
provide: APP_INITIALIZER,
multi: true,
useFactory: setUpRenderFlushing,
deps: [NgZone, RendererFactory2]
}
];
@NgModule({
providers: CONSOLE_MODULE_PROVIDERS,
exports: [CommonModule, ApplicationModule]
})
export class ConsoleModule {
constructor(@Optional() @SkipSelf() @Inject(ConsoleModule) parentModule: ConsoleModule | null) {
if (parentModule) {
throw new Error(
`ConsoleModule has already been loaded.`
);
}
}
}
main.ts
(在我的测试应用程序中)
const __Zone_disable_XHR = true;
import 'zone.js';
import 'reflect-metadata';
import { enableProdMode, CompilerFactory, COMPILER_OPTIONS } from '@angular/core';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { platformConsole } from '../platform_console';
if (environment.production) {
enableProdMode();
}
platformConsole().bootstrapModule(AppModule)
.catch(err => console.error(err));
app.module.ts
(在我的测试应用程序中)
/* imports, etc */
@NgModule({
declarations: [
AppComponent,
ChildComponent
],
imports: [
ConsoleModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
我正在使用 angular-build:server 构建器,因为它似乎是其中最直接的一个。在使用 CLI 启动一个全新的 Angular 应用程序后,其他所有内容几乎都是您所得到的。
错误
一切都很好地编译成一个 main.js 文件,但是当我运行它时,我得到一个错误:
throw new Error("No NgModule metadata found for '" + stringify(type) + "'.");
^
Error: No NgModule metadata found for 'AppModule'.
at NgModuleResolver.resolve ((project root)\node_modules\@angular\compiler\bundles\compiler.umd.js:20020:27)
at CompileMetadataResolver.getNgModuleMetadata ((project root)\node_modules\@angular\compiler\bundles\compiler.umd.js:18662:47)
at JitCompiler._loadModules ((project root)\node_modules\@angular\compiler\bundles\compiler.umd.js:26085:55)
at JitCompiler._compileModuleAndComponents ((project root)\node_modules\@angular\compiler\bundles\compiler.umd.js:26066:40)
at JitCompiler.compileModuleAsync ((project root)\node_modules\@angular\compiler\bundles\compiler.umd.js:26026:41)
at CompilerImpl.compileModuleAsync ((project root)\node_modules\@angular\platform-browser-dynamic\bundles\platform-browser-dynamic.umd.js:202:35)
at compileNgModuleFactory__PRE_R3__ ((project root)\node_modules\@angular\core\bundles\core.umd.js:17664:25)
at PlatformRef.bootstrapModule ((project root)\node_modules\@angular\core\bundles\core.umd.js:17847:20)
at Module../src/main.ts ((project root)\dist\main.js:444:77)
at __webpack_require__ ((project root)\dist\main.js:20:30)
我在这里想念什么?为什么我的元数据没有进入编译包?
我想知道是不是因为我正在使用 JitCompiler,也许服务器构建器将我的文件视为 Aot... 如果是这种情况,我如何创建和使用 AotCompiler 而无需从刮?
笔记
仅使用填充到 platformServer 中的渲染器,我就能够成功运行,但我无法从组件内部访问 Node(我想那里有一些浏览器沙箱在起作用)。这是一个交易破坏者,因为我打算实现与操作系统的节点级接近性与 Angular 等人提供的所有动态/反应性优点的梦想组合。最终,我想用一个合适的 EventManager 来扩展这个新生平台,该 EventManager 由 Node 的事件以及人们期望在终端内拥有的任何其他服务驱动。
我发现很难找到有关在这层 Angular 中工作的信息。
感谢您的时间。