Angular 中缺少组件,但它具有构造函数中提到的服务,未在组件本身内部使用。 JHipster 应用程序

Missing component in Angular when it has service mentioned in constructor, non used inside the component itself. JHipster app

这是我们在浏览器调试中的内容:

const Mp = {
        pageTitle: "ученику"
    }
      , Ap = {
        path: "to-student",
        component: Fp,
        data: Mp,
        canActivate: [m.b]
    };
    class Dp {
        constructor() {}
        ngOnInit() {}
    }

有趣的是,使用 npm start 它编译得很好,只有在生产端(heroku)使用 maven 的 npm 插件构建时才会在运行时失败。

在模块中我们有:

import {
  BlogDocumentsComponent,
  BlogFaqComponent,
  BlogEntriesComponent,
  ShopComponent,
  ShopSuccessComponent,
  ShopFailureComponent,
  SyllablesComponent,
  RedirectComponent,  
  //  UsefulStuffComponent actually not there
} from './';

import 'd3';
import 'nvd3';
import { NvD3Module } from 'ng2-nvd3';
import { UsefulStuffComponent } from './useful-stuff/useful-stuff.component';

所以UsefulStuffComponent不是common import,但是它的路径是正确的!

而且在模块对应的index.ts中并没有提到(我们永远不需要它,如果设置了完整路径,对吧?)

因此,可以通过明确地使 UsefulStuffComponentindex.ts 中导出并以相同的方式与其他组件一起导出来解决该问题:

import {
  BlogDocumentsComponent,
  BlogFaqComponent,
  BlogEntriesComponent,
  ShopComponent,
  ShopSuccessComponent,
  ShopFailureComponent,
  SyllablesComponent,
  RedirectComponent,  
  UsefulStuffComponent actually not there
} from './';

import 'd3';
import 'nvd3';
import { NvD3Module } from 'ng2-nvd3';
//  import { UsefulStuffComponent } from './useful-stuff/useful-stuff.component'; actually no import here

那么,为什么我遇到这种生产运行时故障,但从来没有在本地 npm start 上遇到过?

更新:

因此,在@Gaël Marziou 的建议下,我尝试将导致组件在生产状态下丢失的更改本地化。我发现这个组件仍然会导致产品错误:

import { Component, OnInit } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { PaymentService } from 'app/businesslogic';
import { JhiAlertService } from 'ng-jhipster';
import { IAccessSubscription } from 'app/shared/model/access-subscription.model';
import { AccessSubscriptionService } from 'app/entities/access-subscription';

@Component({
  templateUrl: './to-student.component.html',
  styleUrls: ['./to-student.component.scss']
})
export class ToStudentComponent implements OnInit {
  accessSubscriptions: IAccessSubscription[] = [];
  accessSubscriptionsIds: number[] = [];

  constructor(
    protected jhiAlertService: JhiAlertService,
    protected accessSubscriptionsService: AccessSubscriptionService,
    protected paymentService: PaymentService
  ) {}

  ngOnInit() {
    this.loadAll();
  }

  loadAll() {
    this.accessSubscriptionsService
      .queryAllMine()
      .pipe(
        filter((mayBeOk: HttpResponse<IAccessSubscription[]>) => mayBeOk.ok),
        map((response: HttpResponse<IAccessSubscription[]>) => response.body)
      )
      .subscribe(
        (res: IAccessSubscription[]) => {
          this.accessSubscriptions = res;
          this.accessSubscriptions.map((item: IAccessSubscription) => {
            this.accessSubscriptionsIds.push(item.id);
          });
        },
        (res: HttpErrorResponse) => this.onError(res.message)
      );
  }

  protected onError(errorMessage: string) {
    this.jhiAlertService.error(errorMessage, null, null);
  }
}

虽然这个已经很好用了:

import { Component, OnInit } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { PaymentService } from 'app/businesslogic';
import { JhiAlertService } from 'ng-jhipster';
import { IAccessSubscription } from 'app/shared/model/access-subscription.model';
import { AccessSubscriptionService } from 'app/entities/access-subscription';

@Component({
  templateUrl: './to-student.component.html',
  styleUrls: ['./to-student.component.scss']
})
export class ToStudentComponent implements OnInit {
  accessSubscriptions: IAccessSubscription[] = [];
  accessSubscriptionsIds: number[] = [];

  constructor(protected jhiAlertService: JhiAlertService, protected accessSubscriptionsService: AccessSubscriptionService) {}

  ngOnInit() {
    this.loadAll();
  }

  loadAll() {
    this.accessSubscriptionsService
      .queryAllMine()
      .pipe(
        filter((mayBeOk: HttpResponse<IAccessSubscription[]>) => mayBeOk.ok),
        map((response: HttpResponse<IAccessSubscription[]>) => response.body)
      )
      .subscribe(
        (res: IAccessSubscription[]) => {
          this.accessSubscriptions = res;
          this.accessSubscriptions.map((item: IAccessSubscription) => {
            this.accessSubscriptionsIds.push(item.id);
          });
        },
        (res: HttpErrorResponse) => this.onError(res.message)
      );
  }

  protected onError(errorMessage: string) {
    this.jhiAlertService.error(errorMessage, null, null);
  }
}

因此,非工作仅包含在从未使用过的构造函数中导入某些服务:

   protected paymentService: PaymentService

一些 Angular 错误确实很难调试,尤其是当它们没有出现在开发版本中时。

每次我遇到这种情况时,我都会回滚我的更改,直到找到罪魁祸首。

如果您是在进行大量更改后执行此操作,您可以使用带有 git bisect 的脚本来识别错误行,当然前提是您的提交很小。

理想情况下,为了避免这种“考古”搜索,您应该从项目开始就实施自动持续集成,这样您就可以确保对生产构建进行更深入的检查会更早地发现错误。