如何排除在Angular 5 Universal应用程序中构建浏览器模块

时间:2018-04-05 15:11:14

标签: angular angular-cli angular5 angular-universal

我正在尝试创建一个Angular Universal应用程序,在构建时构建一个特定的路径,将AppShell注入Index.html页面,以便尽快在用户面前获取有意义的内容(而Angular应用程序是下载)。我按照Angular University上的说明进行操作,并按指示操作。但是,当我系统地将我现有应用程序的功能添加到此测试应用程序中时,我遇到了“意外的令牌导入”错误源于我需要的第三方插件浏览器应用程序,但对于非常简单的服务器应用程序我不需要我正在尝试构建并注入Index.html作为我的App Shell。

我花了几个小时研究这个并发现很多帖子推荐webpack,但是,我正在使用Angular CLI。我不确定如何将webpack与Angular CLI构建过程合并。

我发现这个post似乎表明你可以使用tsconfig.server.json的exclude部分从Angular Universal构建中排除模块。我已经尝试列出要在tsconfig.server.json中排除的模块,但是,我仍然收到'意外的令牌导入'错误。

我有一条路线需要构建并注入我的索引页面。我希望/我认为我应该能够排除我的绝大多数应用程序,因为它与创建AppShell无关。我认为Angular应该简单地构建为服务器应用程序注册的路由所需的必要位。

我使用的是Angular CLI 1.7.3版和Angular 5.2.4版。

是否有人了解如何将不必要的模块排除在Angular Universal应用程序中?

感谢您的时间。

2 个答案:

答案 0 :(得分:4)

您可以尝试专门为浏览器创建第三个模块。 此BrowserModule将包含您在浏览器中所需的所有内容。

import { NgModule } from '@angular/core';    
import { AppModule} from './app.module';
import { AppComponent } from './app.component';
// other browser exlusive imports

@NgModule({
  imports: [
    // browser exlusive imports
    AppModule
  ],
  bootstrap: [AppComponent]
})
export class AppBrowserModule { }

然后你在main.ts文件中引导这个新模块而不是你的AppModule。这个方法也在StackOverflow问题中讨论:Need BrowserAnimationsModule in Angular but gives error in Universal
这里要在服务器上排除的模块是BrowserAnimationsModule,但它对于你不需要的任何其他模块应该是相同的。服务器。
如果您需要在浏览器中包含脚本,可以在main.ts中导入它们,它们应该可用于整个应用程序。

如果你需要检查你是否在浏览器上,你可以使用isPlatformBrowser from angular:https://angular.io/api/common/isPlatformBrowser
@Optional Decorator也可以非常方便(https://angular.io/api/core/Optional),如果你想通过Dependency Injection在你的一个组件或服务中的浏览器中包含一些内容。
您可能需要这些来防止由于服务器呈现的应用程序上缺少文件而导致的错误。

您描述的导入错误是由第三方库未正确构建其库引起的。解决此问题的一种简单方法是在抛出这些错误的文件上使用babel。 例如,如果您有一个名为“failingPackage”的包:

babel ./node_modules/failingPackage -d ./node_modules/failingPackage --presets es2015

您基本上正在编译已损坏程序包的所有文件,并使用新文件覆盖旧文件。我告诉你这个方法,因为你可能会在你想要在服务器渲染的应用程序上使用的包上遇到这个错误。

您可以在此处详细了解此问题:https://github.com/angular/angular-cli/issues/7200

这里讨论带有babel的解决方案:https://github.com/SebastianM/angular-google-maps/issues/1052 完全归功于Anthony Nahas。

或者您可以尝试此解决方案:"Unexpected token import" error with Angular4 + Universal + ng-bootstrap

  • 使用ng eject创建webpack.config.js
  • 安装webpack-node-externals
  • 将webpack.config.js
  • 的外部部分中的失败包列入白名单

答案 1 :(得分:0)

以下方法适合我。让我们说我想使用浏览器动画库PIXI.js.所以,在这里。请注意,我在import条件下使用if (this.isBrowser)。因此,只有当平台是浏览器时,才会导入和执行库。

import { AfterViewInit, Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { Router } from '@angular/router';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';

@Component({
  selector: 'app-front-face',
  templateUrl: './front-face.component.html',
  styleUrls: ['./front-face.component.scss']
})
export class FrontFaceComponent implements OnInit, AfterViewInit {

  constructor(private router: Router,
    @Inject(PLATFORM_ID) private platformId: string) { }

  ngOnInit() {
    this.isBrowser = isPlatformBrowser(this.platformId);
  }

  constructor(private router: Router,
    @Inject(PLATFORM_ID) private platformId: string) { }

  ngOnInit() {
    this.isBrowser = isPlatformBrowser(this.platformId);
  }

  ngAfterViewInit() {
    if (this.isBrowser) {

        import('pixi.js').then(PIXI => {
          this.renderer = PIXI.autoDetectRenderer({ transparent: true });
          this.stage = new PIXI.Container();
          // Other PIXI related calls
        });
    }
  }
}