代码之家  ›  专栏  ›  技术社区  ›  Tom Schreck

如何在Angular 5 Universal app中排除内置的浏览器模块

  •  4
  • Tom Schreck  · 技术社区  · 6 年前

    我正在尝试创建一个角度通用的应用程序,在构建时构建一个特定的路由,以便将AppShell注入索引。html页面作为一种手段,可以在用户面前尽快获得有意义的内容(Angular应用程序正在下载)。我正在遵循 Angular University 我让它按照指示工作。然而,当我系统性地将现有应用程序的功能添加到此测试应用程序中时,我遇到了“意外令牌导入”错误,该错误源于浏览器应用程序所需的第三方插件,但对于我尝试构建并注入索引的非常简单的服务器应用程序来说,这不是必需的。html作为我的应用程序外壳。

    我花了几个小时研究这个问题,发现有很多帖子推荐webpack,然而,我使用的是Angular CLI。我不知道如何将webpack与Angular CLI构建过程结合起来。

    我找到了这个 post 这似乎表明您可以使用tsconfig的exclude部分从角度通用构建中排除模块。服务器json。我尝试在tsconfig中列出要排除的模块。服务器然而,json仍然出现“意外令牌导入”错误。

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

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

    有人知道如何将不必要的模块排除在Angular Universal应用程序中吗?

    谢谢你的时间。

    2 回复  |  直到 6 年前
        1
  •  7
  •   darron614    6 年前

    您可以尝试专门为浏览器创建第三个模块。 此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 { }
    

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

    如果需要检查是否在浏览器上,可以从angular(角度)使用iPlatformBrowser(iPlatformBrowser): https://angular.io/api/common/isPlatformBrowser
    @Optional Decorator也非常方便( https://angular.io/api/core/Optional ),如果您希望仅在浏览器的某个组件或服务中通过依赖项注入包含某些内容。
    您可能需要这些工具来防止由于服务器呈现的应用程序上缺少文件而导致的错误。

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

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

    您基本上是在编译损坏包的所有文件,并用新文件覆盖旧文件。我告诉您这种方法,因为您可能会在要在服务器呈现的应用程序上使用的包上遇到此错误。

    您可以在此处阅读有关此问题的更多信息: https://github.com/angular/angular-cli/issues/7200

    巴别塔的解决方案如下: https://github.com/SebastianM/angular-google-maps/issues/1052 安东尼·纳哈斯获得了全部荣誉。

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

    • 使用ng eject创建网页包。配置。js公司
    • 安装Web包节点外部
    • 在网页的外部部分列出失败的包。配置。js公司
        2
  •  0
  •   Saptarshi Basu    6 年前

    以下方法适用于我。假设我想使用浏览器动画库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
            });
        }
      }
    }