1

Here what we have in browser's debug:

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

enter image description here

It is interesting, that with npm start it is compiled well and fails in runtime only when it is built with npm plugin of maven on production side (heroku).

At the module we have:

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';

so UsefulStuffComponent is not in common import, but its path is correct!

And it is not mentioned in the corresponding index.ts of the module (we don't need it ever, if the full path is set, right?)

So the problem can be fixed by explicitly making UsefulStuffComponent be exported in index.ts and being exported with other component the same way:

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

So, why I'm getting this kind of production runtime failure, but never get it on npm start locally?

UPD:

So, after the advice of @Gaël Marziou I have tried to localize the change that made the component to be lost at prod state. I have reveal that this component still causes the prod error:

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);
  }
}

while this one already works well:

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);
  }
}

So, non-working just contains an import of some service in the constructor that isn't ever used:

   protected paymentService: PaymentService
Eljah
  • 4,188
  • 4
  • 41
  • 85
  • 1
    A prod build does more things than a dev build: template checkings, tree shaking, AOT. If a component is not used, it's very likely that it'll get removed by tree shaking. – Gaël Marziou Sep 16 '20 at 12:23
  • @GaëlMarziou how can I start the npm build process that excactly the same as in prod locally to get this error and debug it on the local env? – Eljah Sep 16 '20 at 13:45
  • See your README, use maven and java -jar – Gaël Marziou Sep 16 '20 at 15:45
  • @GaëlMarziou the most intriguing for me, that it fails when I build it with `-Pprod` due to some typescript errors, and it is ok and the build succeed when `-Pwar` is used. In heroku it looks like it is built as `-Pwar`, but not `-Pprod` and thus the npm part with `-Pwar` succeed, but has failed in runtime. How can I figure out where the exact profiles are selected at heroku build from branch? It is not a `Procfile`, but where? I'd like to set up the same build failures locally, with `-Pprod` and how it is build on heroku. And the IDE highlighting of errors also should be the same. – Eljah Sep 16 '20 at 18:27
  • And when it fails on -Prod build, no errors thrown are related to the missed component (no errors for this route-component-template at all, just some other syntax errors) – Eljah Sep 16 '20 at 18:41
  • 1
    I added heroku tag to your question maybe it'll bring some attention to it. I suppose you could find out by looking at heroku sub generator source: https://github.com/jhipster/generator-jhipster/tree/master/generators/heroku – Gaël Marziou Sep 16 '20 at 20:17
  • @GaëlMarziou I have checked what I have in `MAVEN_CUSTOM_OPTS` that defines deploy on heroku and it is `clean package -Pprod,heroku,swagger -DskipTests`. And `-DskipTest` is critical here. Whithout it the build is failed, but due to some other problems and noone points the component missed in the prod. I have added `-DskipTests` here for disabling them on Java backend part (yes, I'm bad-ass, I know it, but I was surprised that it affects the npm building somehow and even more, makes it passed, but then failed on the prod) – Eljah Sep 17 '20 at 07:05
  • Yes that's why it's important to have a continuous integration even if you are using Heroku – Gaël Marziou Sep 17 '20 at 08:03
  • @GaëlMarziou so for me it is currently actual to find any error pointing to the particular component removing when tree shaking is done, as I don't know what is particular error in the typescript codebase. Is there a way to run -Pprod npm part with a kind of debug that will make me know, what is actually thrown by tree shaking and why? Because when it run it without -DskipTest, I don't have any error related to this component when the build is failed. – Eljah Sep 17 '20 at 08:58
  • 1
    Honestly, I don't know maybe you can find it angular docs. Each time I faced such situation I actually rolled back until I found the culprit commit, this is why CI helps here. If you're doing after lot of changes, maybe you could use a script with `git bisect` to identify the faulty lines assuming your commits are small of course. – Gaël Marziou Sep 17 '20 at 11:00
  • @GaëlMarziou is there a way to make time being heroku prod build be the same as fast dev build? I.e. remove timely tree shaking phase just to check the problem comes really from it? Do we have some run parameters that can be applied there for npm task of front end plugin? – Eljah Sep 21 '20 at 07:40
  • 1
    Anything you can run with 'npm run' can be configured in pom.xml, see frontend maven plugin documentation https://github.com/eirslett/frontend-maven-plugin/blob/master/README.md Fast dev builds and tree shaking are opposite, you can't have both otherwise it would be the default. – Gaël Marziou Sep 23 '20 at 08:44
  • @GaëlMarziou according to your advice I have fuigured out the specific line that causes the problem. But I can't find out what actually is violated in that line. – Eljah Sep 25 '20 at 10:28
  • @GaëlMarziou I have updated the question body – Eljah Sep 25 '20 at 10:41
  • I had something similar related to dependency injection and I could not find why. It could be a problem of import or of a circular dependency involving more than 2 services/components. Either you can fix it (google for angular circular dependency) without changing you design or you consider that it reveals a design flaw or you refactor your code to avoid it – Gaël Marziou Sep 26 '20 at 16:45
  • @GaëlMarziou we should report this as an issue to frontend maven plugin or npm utility support of whatever, shouldn't we? Anyway silent prod fail with very tricky way to find what is wrong isn't ok and I belive it should be reported somewhere. – Eljah Sep 27 '20 at 18:10
  • 1
    I'm not sure it's an issue with frontend maven plugin, it could be an angular compiler issue, Anyway, if you want to report it to one of these projects, you will be asked to provide a minimal project to reproduce the problem. – Gaël Marziou Sep 28 '20 at 17:35
  • @GaëlMarziou please post your advice on searching for the wrong commit as the official answer, as that is the best thing that can help here for other people facing the same problem in general. – Eljah Oct 06 '20 at 07:41
  • 1
    Done, useful for people that would not want to go through all our comments :) – Gaël Marziou Oct 06 '20 at 08:45

1 Answers1

1

Some Angular errors can really be difficult to debug especially when they don't appear in dev builds.

Each time I faced such situation I actually rolled back my changes until I found the culprit commit.

If you're doing it after lot of changes, you can use a script with git bisect to identify the faulty lines assuming your commits are small of course.

Ideally, to avoid this "archaeological" search, you should put in place automatic continuous integration from beginning of your project, this way you are sure that deeper checkings from production builds will catch errors earlier.

Gaël Marziou
  • 16,028
  • 4
  • 38
  • 49