我正面临Angular2 AoT的挑战,因为我被困住了,任何帮助对我来说都是一个很大的帮助。
我有一个简单的hello world应用程序,它有main.js,home.module.ts,home.component.ts,home.component.html和home.service.ts。这个代码在没有AoT的情况下使用Angular2很有效。
在我按照cookbook中的angular.io步骤精确执行AoT和Rollup后,我收到错误:“未捕获的ReferenceError:模块未定义”,我不知道为什么会发生这种情况。
My Home.Component.ts标记如下:
@Component({
selector: 'rf-home',
moduleId: module.id, // i m setting this module.id so that I can use relative template paths in my code. Helps in Dev env.
templateUrl: 'Home.component.html',
providers: [HomeService]
})
有人在那里,请帮忙!
答案 0 :(得分:3)
从Angular 2.1开始,文档的AOT部分(https://angular.io/docs/ts/latest/cookbook/aot-compiler.html)有一个更简单的方法。
<script>window.module = 'aot';</script>
这一行放在aot build的index.html文件中。
我正在使用的修复是添加一个自定义提供程序,用于检查模块对象是否在浏览器中可用,如果找不到则将其添加到全局范围。
创建以下类:rollup-module.provider.ts
export function RollupModuleProvider(params: any) {
return function (target: any) {
// Setup the 'module' variable globally. The rollup javascript has its own module system, but there is still a
// reference to the Commonjs module.id in the code, so setup a module object to allow that code to execute
// without throwing an exception
try {
// In dev mode with commonjs the following line will execute without a problem
// In AoT mode with rollup the following line will trigger an exception that will be
// caught and handled to allow the AoT build to run without issue
let testIfRunningWithCommonJSandModuleIsAvailable = module.id;
} catch (e) {
// Declare Module for rollup based production builds.
// When running dev builds CommonJS automatically provides the module definition
console.log("Defining Module");
var globalScope: any;
if (typeof window === 'undefined') {
globalScope = global;
}
else {
globalScope = window;
}
globalScope.module = "test";
try {
let moduleShouldBeAvailable = module;
}
catch (e) {
// Our attempt to register module failed so we are not in an unrecoverable error state.
console.error("Module not defined");
}
}
}
}
在app.component.ts中添加以下代码段。请注意,app.component.ts应该是&#34; bootstrap&#34;中的类。 app.module.ts文件中的声明。
import {RollupModuleProvider} from "./rollup-module.provider";
@RollupModuleProvider({})
为了完整性,这是下面的完整app.component.ts。注意我内联此组件中的模板以进一步简化构建。对于应用程序中的其他组件&#39;模板&#39;可用于内联html或&#39; templateUrl&#39;可以用来将html放在一个单独的文件中。对于除主app.component.ts之外的所有组件,此选择可以基于个人/项目偏好。
import { Component } from '@angular/core';
import './rxjs-operators';
import {ModalService} from "./shared/modal.service";
import {RollupModuleProvider} from "./rollup-module.provider";
@RollupModuleProvider({})
@Component({
selector: 'myapp',
/* For only the top level component inline the template which simplifies the build process. By in-lining the
* template we don't need to setup the "module: module.id" on the Component decorator. We use the RollupModuleProvider
* to setup the module variable when running in a ngc/rollup build. In a dev build the CommonJs module system is used
* so module.id is available. In a ngc/rollup build the module does not need to be set on the component so it can be
* set to a valid value and then is essentially ignored.
*/
template:
`<div [class.modalDisplayed]="modalService.isModalDisplayed()"></div>
<nav-header></nav-header>
<div class="container-fluid">
<router-outlet> </router-outlet>
</div>`
})
export class AppComponent {
constructor (public modalService: ModalService) {
}
}
这是完整的app.module.ts。
import {NgModule} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { Logger } from './logger.service';
import { HttpClient } from './http.client.service';
import {WindowSize} from './window-size.service';
import {ModalService} from "./shared/modal.service";
import {SharedModule} from "./shared/shared.module";
@NgModule({
imports: [BrowserModule, HttpModule, routing, SharedModule],
declarations: [AppComponent],
providers: [ Logger, HttpClient, WindowSize, ModalService ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
作为解决方案的一部分,我希望能够将moduleId定义留在代码中,以便我可以继续运行tsc并使用commonjs进行开发。 AoT不需要moduleId来运行。 UncaughtReferenceError出现在具有AoT构建的浏览器中,因为浏览器没有&#34; module&#34;在全局范围内可用(通常是JavaScript窗口对象)。在开发模式下,commonjs设置模块,因此没有问题。
由于AoT不需要moduleId,因此修复是在AoT模式下运行时在浏览器中简单设置模块对象。除了被定义以避免抛出引用错误之外,模块对象不必做任何事情。
设置全局范围的代码来自角度2代码库,只是稍微修改了这个用法。
答案 1 :(得分:1)
修复此错误的另一种方法:
将 templateUrl:'Home.component.html'替换为 的模板: 要求( '到字符串!./ Home.component.html.html')强>
@Component({
选择器:'rf-home',
template:require('to-string!./ Home.component.html.html'),
提供者:[HomeService]
})