Angular: Angular2 AOT-Kompilierung - "Das Modul für die Klasse kann nicht bestimmt werden (... viele Komponenten, die nicht verwendet werden)"

Erstellt am 20. Dez. 2016  ·  183Kommentare  ·  Quelle: angular/angular

[ x ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Aktuelles Verhalten
Nicht verwendete Komponenten/Pipes/Direktiven in meinem Arbeitsbereich werden vom Compiler erkannt, der den Fehler Cannot determine the module for class (...) für jede Datei ausgibt. Es stoppt die Kompilierung und scheint nicht konfigurierbar zu sein. Dies ist ein Problem, da ich diese Dateien in meinem Arbeitsbereich haben muss, sie aber nicht in der resultierenden App benötige (Partnerimplementierungen erfordern unterschiedliche Kombinationen von gemeinsam genutzten Komponenten). Dies ist besonders frustrierend im Hinblick auf das Kompilieren in einem Webpack-Loader, der in der Lage sein sollte, unabhängig vom Arbeitsbereich eine Liste der enthaltenen Dateien bereitzustellen.

Erwartetes Verhalten
Ich würde erwarten, dass diese Fehler Warnungen sind und/oder durch eine Compileroption zum Schweigen gebracht werden können. Alternativ könnten Sie in Bezug auf das Webpack zulassen, dass eine Liste von Dateien eingefügt wird, sodass ein Webpack alle Dateien in der Anforderungskette anstelle aller Dateien im Arbeitsbereich bereitstellen könnte.

Minimale Reproduktion des Problems mit Anleitung
Kann nicht in plunkr demonstriert werden, da es JIT verwendet.

  1. Erstellen Sie eine einfache Winkel-App, die ein ngModule mit einer Komponente, AppComponent, bootet
  2. Bringen Sie diese App in einen Zustand, der AOT-kompiliert werden kann (sollte mit einem Hallo Welt ziemlich einfach sein)
  3. Fügen Sie der Verzeichnisstruktur eine Komponente hinzu, aber verweisen Sie nirgendwo in Ihrem Code darauf.
  4. Versuchen Sie erneut, AOT zu kompilieren. Sie erhalten die Warnung Cannot determine the module for class

Was ist die Motivation / der Anwendungsfall für die Änderung des Verhaltens?
Mein Unternehmen hat eine Basis-App für uns selbst, und unsere Partner verwenden modifizierte Versionen dieser App als ihre eigene. Anstatt alle Partner separat zu pflegen, verwenden wir eine gemeinsam genutzte Bibliothek gemeinsamer generischer Komponenten, die nach Bedarf importiert werden. Für unsere Basis-App ist alles in Ordnung, da wir alle Komponenten verwenden. Für Partner können wir AOT nicht verwenden, da einige der Komponenten im gemeinsam genutzten npm-Paket kein deklariertes Modul haben.

Bitte teilen Sie uns Ihre Umgebung mit:
Passiert auf allen Geräten, aber das aktuelle Test-Setup ist:
Windows 10
VS-Code
Cmder (Bash-Terminal)

  • Winkelversion:
    v2.1.0 (obwohl wir auch in 2.3.1 getestet haben

  • Browser: Alle - Dies ist ein Compiler-Problem, nicht browserspezifisch

  • Sprache: Maschinenschrift

  • Knoten (für AoT-Probleme): Knoten v6.3.0
P5 compiler NgModule ve low error messages triage #1 confusing

Hilfreichster Kommentar

@DzmitryShylovich Es ist sinnvoll, dass Komponenten, die Sie VERWENDEN, Teil eines Moduls sein müssen. Aber für den Compiler sollten diese Dateien keine Rolle spielen. Sie sind unbenutzte, nicht referenzierte .ts-Dateien, die Komponenten enthalten.

Alle 183 Kommentare

Das Modul für die Klasse kann nicht bestimmt werden

Die Komponente muss Teil eines Moduls sein. Es ist beabsichtigt.
Ich würde sagen, es ist ein Feature-Request.

@DzmitryShylovich Es ist sinnvoll, dass Komponenten, die Sie VERWENDEN, Teil eines Moduls sein müssen. Aber für den Compiler sollten diese Dateien keine Rolle spielen. Sie sind unbenutzte, nicht referenzierte .ts-Dateien, die Komponenten enthalten.

@swimmadude66 Sie können unbenutzte Dateien in tsconfig ausschließen

@DzmitryShylovich kannst du, aber Fassdateien erschweren das. Wenn eine Klasse in eine Barrel-Datei erneut exportiert wird, muss ich die Barrel-Datei ebenfalls ignorieren, was zu Problemen mit den Klassen führen kann, die ich aus diesem Barrel benötige.

Es scheint seltsam, dass der Compiler versuchen sollte, mehr zu kompilieren, als er unbedingt muss. Abgesehen vom Baumschütteln würde ich erwarten, dass der Compiler nur mit Dateien umgehen möchte, die ihm gegeben oder explizit mit bestimmten Dateien verknüpft sind.

Es scheint seltsam, dass der Compiler versuchen sollte, mehr zu kompilieren, als er unbedingt muss.

So funktionieren Compiler...

Die Tatsache, dass die JIT-Kompilierung funktioniert, sollte ein ziemlich guter Beweis dafür sein, dass der Compiler diese Dateien nicht benötigt. Es gibt einen Fehler statt einer Warnung für Dateien aus, die ohne Schaden ausgeschlossen werden könnten.

Sie können mit mir darüber reden, wie Compiler den ganzen Tag arbeiten, aber das ist ein echtes Problem in einem etwas einfachen Anwendungsfall. Ich frage nur nach einer Möglichkeit, den Fehler zumindest zu unterdrücken und auf eigenes Risiko fortzufahren.

Mein Kollege versucht, alle Barrel-Dateien zu entfernen, die uns daran hindern könnten, pauschale Ausschlüsse zu verwenden, aber ich möchte Sie bitten, sich das Problem anzusehen, das ich ursprünglich gegen @ngtools/webpack geöffnet habe, wo ein anderer Benutzer denselben Fehler hatte eine Komponente, auf die nur in ihren Tests verwiesen wird. https://github.com/angular/angular-cli/issues/3636

Der Compiler kennt Dateien, die ich nicht kompilieren möchte, und gibt nicht behebbare Fehler für behebbare Situationen aus. einfach so.

Ich verstehe nicht, warum Sie Komponenten im selben Verzeichnis haben, die nicht im Projekt enthalten sind.
Ich denke, dies könnte eine Feature-Anfrage sein, aber derzeit funktioniert der Compiler so, und auch zu sagen, dass "es in JIT funktioniert", ist nicht Grund genug zu glauben, dass es in AOT funktionieren sollte.
Ich denke, Sie müssen diese Dateien aus Ihrer Basis-App in Module aufteilen und sie dann über eine Art Paketmanager importieren. Auf diese Weise werden Ihre Probleme gelöst, Ihr Verzeichnis aufgeräumt und die Wartung in jeder Hinsicht erleichtert

@Toxicable Die nicht verwendeten Dateien befinden sich in einem npm-Modul im Bibliotheksstil. Im Allgemeinen sieht der ideale Anwendungsfall so aus:

In @project/angular (unser gemeinsam genutztem Code-npm-Modul) haben wir alle Komponenten, Pipes, Anweisungen und Dienste, die zum Erstellen unserer Basis-App und zum Kommunizieren mit unserer Backend-Plattform erforderlich sind. Unsere Partner möchten eine App, die ähnlich aussieht, aber eine andere Startseite verwendet oder der eine neue Komponente hinzugefügt wurde. Die meisten anderen Seiten werden jedoch gleich sein, und alle Dienste, die für die Verbindung zu unserer Plattform erforderlich sind, könnten gleich sein.

Unser Ansatz zur Maximierung des wiederverwendbaren Codes bestand darin, jeden Partner dazu zu bringen, Module zu erstellen und eine Kombination aus neuen Teilen und gemeinsam genutzten Teilen aus dem npm-Modul zu importieren. Mein neues HomeModule könnte einen Import haben wie:

import {
    OverviewComponent,
    ProfileComponent
} from './components/home';

import {
    AuthComponent
} from '@project/angular';

Dies explodiert dann in AOT und sagt: Cannot determine the module for class OverviewComponent , da wir die OverviewComponent von @project/angular nicht verwenden.

Da buchstäblich keine Dateien auf @project/angular/components/home/overview/component.ts verweisen, würde ich nicht erwarten, dass sich der Compiler darum kümmert, dass es nicht verwendet wird. aber da die Datei im Verzeichnis node_modules unseres Projekts existiert, findet der Compiler sie, beschwert sich und stirbt.

Was JIT funktioniert!== AOT funktioniert, die Basis-App funktioniert mit AOT, und die Änderungen beim Proof-of-Concept-Partner sind unglaublich gering. Ich will damit nicht sagen, dass alles, was in JIT funktioniert, auch in AOT funktionieren sollte, aber ich habe sehr guten Grund zu der Annahme, dass dies der Fall sein sollte.

Ich habe ein weiteres Beispiel, bei dem dieses aktuelle Verhalten keinen Sinn ergibt - Tests.
Angenommen, ich habe ein Feature-Verzeichnis some-feature mit some-feature.component.ts und some-feature.component.spec.ts .
Diese Komponente verwendet die Inhaltsprojektion, daher möchte ich diese Funktionalität testen, indem ich eine Testkomponente in meiner some-feature.component.spec.ts -Datei erstelle , die die some-feature -Komponente in der Ansicht verwendet, etwa so:

@Component({
  selector: 'test-app',
  template: `<some-feature><p>projected content</p></some-feature>`
})
export class TestAppComponent {}

Diese Komponente verwende ich dann in meinem Testmodul :

  ...
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [TestAppComponent, SomeFeatureComponent]
    })
  })
  ...

Alles ist gültig und großartig, bis ich ng build --prod --aot mit angle-cli ausführe, was Folgendes auslöst:
Cannot determine the module for class TestAppComponent .

Ich denke nicht, dass sich AOT mit .spec -Dateien befassen sollte.

Die allgemeine Regel lautet: ngc kompiliert alles, was tsc kompiliert. Und es wird versuchen, jede gefundene Komponente zu kompilieren. Angular kann jedoch keine Komponenten ohne ein zugehöriges Modul kompilieren.

Wir könnten diesen Fehler jedoch in eine Warnung umwandeln.

Ich habe auch Test-Wrapper-Komponenten, die nur zum Testen verwendet werden und die dazu führen, dass AOT wie hier beschrieben explodiert. Wäre schön, wenn AOT alle Komponenten ignorieren könnte, die einen Platzhalterausdruck wie TestComponent* usw. erfüllen.

Okay, also mehr Infos hier. Wir scheinen eine Problemumgehung für unseren Fall gefunden zu haben (behebt den TestWrapper-Fall nicht). Es scheint, dass das eigentliche Problem in unserem Fall unsere Fassdateien waren. Wenn Sie ALLES aus einer Fassdatei importieren, folgt es der Kette aller Dinge, die von den Fässern erneut emittiert werden. Da wir unsere Komponenten von einer obersten Ebene PROJECT/components eingezogen haben, wurden ALLE Komponenten analysiert, anstatt nur die eine, die wir wollten. Dies wäre wahrscheinlich immer noch besser als Warnung, aber ich kann etwas besser verstehen, warum sich der Compiler um diese Komponenten gekümmert hat.

gleichen Fehler sehen:

$ ./node_modules/.bin/ng-xi18n
Error: Cannot determine the module for class DividerPanel in C:/msweb/studiotouch/src/comps/dividerpanel/DividerPanel.ts!
Cannot determine the module for class EntryPanel in C:/msweb/studiotouch/src/comps/entry/EntryPanel.ts!
Cannot determine the module for class ForgotPass in C:/msweb/studiotouch/src/comps/entry/ForgotPass.ts!
Cannot determine the module for class Footer in C:/msweb/studiotouch/src/comps/footer/Footer.ts!
Cannot determine the module for class Infobox in C:/msweb/studiotouch/src/comps/infobox/Infobox.ts!
Cannot determine the module for class InputNumeric in C:/msweb/studiotouch/src/comps/inputnumeric/InputNumeric.ts!
Cannot determine the module for class InputString in C:/msweb/studiotouch/src/comps/inputstring/InputString.ts!
Cannot determine the module for class Loading in C:/msweb/studiotouch/src/comps/loading/Loading.ts!
Cannot determine the module for class MapAddress in C:/msweb/studiotouch/src/comps/mapaddress/MapAddress.ts!
Cannot determine the module for class Minitab in C:/msweb/studiotouch/src/comps/minitabs/MiniTab.ts!
Cannot determine the module for class Minitabs in C:/msweb/studiotouch/src/comps/minitabs/MiniTabs.ts!
Cannot determine the module for class ModalDialog in C:/msweb/studiotouch/src/comps/modaldialog/ModalDialog.ts!
Cannot determine the module for class Ng2Highcharts in C:/msweb/studiotouch/src/comps/ng2-highcharts/src/directives/ng2-highcharts.ts!

Cannot determine the module for class Ng2Highstocks in C:/msweb/studiotouch/src/comps/ng2-highcharts/src/directives/ng2-highstocks.ts!

Cannot determine the module for class Ng2Highmaps in C:/msweb/studiotouch/src/comps/ng2-highcharts/src/directives/ng2-highmaps.ts!
Cannot determine the module for class simplelistEditable in C:/msweb/studiotouch/src/comps/simplelist/simplelistEditable.ts!
Cannot determine the module for class simplelist in C:/msweb/studiotouch/src/comps/simplelist/simplelist.ts!
Cannot determine the module for class FilterPipe in C:/msweb/studiotouch/src/pipes/FilterPipe.ts!
Cannot determine the module for class FilterPipeEqual in C:/msweb/studiotouch/src/pipes/FilterPipeNot.ts!
Cannot determine the module for class OrderBy in C:/msweb/studiotouch/src/pipes/OrderBy.ts!
Cannot determine the module for class ReplacePipe in C:/msweb/studiotouch/src/pipes/ReplacePipe.ts!
Cannot determine the module for class SortBy in C:/msweb/studiotouch/src/pipes/SortBy.ts!
    at analyzeAndValidateNgModules (C:\msweb\studiotouch\node_modules\@angular\compiler\bundles\compiler.umd.js:24878:17)
    at Extractor.extract (C:\msweb\studiotouch\node_modules\@angular\compiler\bundles\compiler.umd.js:27727:20)
    at Extractor.extractBundle (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extractor.js:40:33)
    at Extractor.extract (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extractor.js:30:34)
    at extract (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extract_i18n.js:7:67)
    at Object.main (C:\msweb\studiotouch\node_modules\@angular\tsc-wrapped\src\main.js:47:16)
    at Object.<anonymous> (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extract_i18n.js:14:9)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
Extraction failed

root@DESKTOP-VEUHFOL /cygdrive/c/msweb/studiotouch

Eckig 2 Küchenspüle: http://ng2.javascriptninja.io
und source@ https://github.com/born2net/Angular-kitchen-sink
Grüße,

Sean

i18 sollte nicht die gesamte Projektstruktur durchlaufen und sich stattdessen die verwendeten Deklarationen ansehen.

Ich habe versucht, die nicht verwendeten Anweisungen zu bereinigen, und das Kaninchenloch wurde gerade tiefer:

$ ./node_modules/.bin/ng-xi18n
Error: Error at C:/msweb/ng-skeleton/node_modules/typescript/lib/lib.d.ts:18770:11: Duplicate identifier 'ActiveXObject'.
Error at C:/msweb/ng-skeleton/node_modules/typescript/lib/lib.d.ts:18773:13: Duplicate identifier 'ActiveXObject'.
Error at C:/msweb/ng-skeleton/e2e/app.po.ts:1:38: Cannot find module 'protractor'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/facade/lang.d.ts:12:17: Cannot find name 'Map'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/facade/lang.d.ts:13:17: Cannot find name 'Set'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_init.d.ts:16:18: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/rxjs/Observable.d.ts:68:60: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/rxjs/Observable.d.ts:68:70: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/linker/compiler.d.ts:53:49: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/linker/compiler.d.ts:61:65: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:116:67: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:132:101: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:158:67: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:160:101: Cannot find name 'Promise'.

Lassen Sie mich hinzufügen, dass mit Angular-Cli und Angle-Compiler alles gut funktioniert, also ist es nur i18, das mein Projekt nicht mag.

Referenz (schönes und sauberes Setup): https://github.com/born2net/ng-skeleton

Grüße,

Sean

Gleicher Fehler für auskommentierte Komponenten. Nicht verwendete und auskommentierte Komponenten für die Entwicklungsphase sind nur ein nützlicher Schritt, um nicht verarbeitet zu werden

// two comments aot read:

//  {path: 'about', component: AboutComponent 
// import { AboutComponent } from './about';

@kirjai ngc kompiliert alle Dateien in einem Quellverzeichnis. Es spielt keine Rolle, ob Sie es importieren oder nicht.

@DzmitryShylovich , was ich verstehe, ich sage nur, dass ich nicht denke, dass sich das AOT in diesem Fall überhaupt um diese Datei kümmern sollte . Meiner Meinung nach ist das Überspringen von .spec-Dateien während der AOT-Kompilierung der richtige Weg. Aber offensichtlich gibt es etwas, das das Team davon abhält, das zu tun, verstehe ich.

Als Alternative sollte das Einfügen von .spec-Dateien in dasselbe Verzeichnis wie die Entität, für die die Tests geschrieben wurden, möglicherweise nicht vom Styleguide vorgeschlagen werden?

Ich stoße auch auf diese Fehlermeldung (und einige andere) wegen unseres Testcodes und AOT in Kombination.

Ich kann diesen Artikel empfehlen. Es erklärt, wie bestimmte Fehlermeldungen provoziert werden können und wie diese behoben/umgangen werden können.

Wenn man bedenkt, dass Leute auf genau dieses Problem stoßen werden, wenn sie dem offiziellen Testleitfaden folgen und ihre App mit AOT erstellen, möchten Sie den Leitfaden vielleicht aktualisieren?

(Wenn jemand nach einer Antwort zu RouterLinkStubDirective sucht)
_Sie können es beheben, indem Sie ein "Dummy"-Modul hinzufügen:_

/**
 * Needed so that `aot` build is working. But it isn't used throughout our tests and/or app.
 */
@NgModule({
    imports: [
        AppModule
    ],
    declarations: [
        RouterLinkStubDirective,
        RouterOutletStubComponent
    ]
})
export class FakeRouterModule {
}

Übrigens versucht es auch, das Modul für abstrakte Klassen zu bestimmen:
export abstract class AsyncTransform extends AsyncPipe implements PipeTransform { ... }

"Fehler: Das Modul für die Klasse AsyncTransform kann nicht bestimmt werden"

Das Hinzufügen zu einem Modul funktioniert auch nicht 😄.
"Ein abstrakter Konstruktortyp kann einem nicht abstrakten Konstruktortyp nicht zugewiesen werden."

dies geschieht auch für einige Klassen.

Fehler: Das Modul für die Klasse AppGlobalModalComponent kann nicht bestimmt werden

export class CustomGlobalModalComponent extends AppGlobalModalComponent {}

@gestj Wie @Phmager betonte, sind Dummy-Module keine Lösung für alle Fälle. Außerdem sind sie eine ziemlich nervige Lösung, da Sie am Ende Code kompilieren, den Sie nicht wollen oder brauchen.

In unserem Fall haben wir das Problem auf andere Weise behoben. Wir haben unsere gemeinsam genutzten Komponenten in eine npm-Bibliothek verschoben und node_modules in unserer tsConfig ignoriert. Ich habe oben erwähnt, dass das immer noch nicht funktioniert, aber nur, weil wir Barrel-Dateien verwendet haben. Wenn Sie direkt auf jede Klasse zeigen, die Sie innerhalb von node_modules benötigen, werden die anderen ignoriert. Sobald Sie jedoch auf ein Fass zeigen, wird der Fehler für die nicht verwendeten Dateien im selben Fass ausgegeben.

Das ist nicht ideal, da es alle unsere wunderbaren Barrel-Dateien tötet, aber zumindest ist es vorhersehbar.

Ich hoffe immer noch, dass dieser Fehler zu einer Warnung herabgestuft wird

Großartige Arbeit, die bisher im Angular-Team geleistet wurde.
Wir verwenden Angular stark in unseren Projekten und nachdem ich ein Jahr lang versucht habe, mich mit all diesen lebhaften Angular2+-Dingen zurechtzufinden, ist hier mein Ergebnis:
1- Angular ist massiv und langsam, willst du es schnell machen? Verwenden Sie AOT und LazyLoading und gzip Ihre Sachen.
2- Du willst eine Komponente faul laden? NEIN, Sie könnten eine Route faul laden. Wenn Ihre App also riesig ist, aber nur eine Seite hat, genießen Sie die Paketgröße von 8 mg.
3- Du willst AOT verwenden ?? AOT ist fehlerhaft und schwer einzuhalten und verwendet nicht jede Menge Javascript/ES6-Funktionen und schreibt wahrscheinlich viele Ihrer Codes neu.
4- Sie verwenden AOT gut? In Ordnung, werfen Sie jetzt einen Blick auf Ihr endgültiges Bundle, es ist jetzt sogar größer als @angular/compiler plus Ihre Komponenten, die nicht AOTed sind, gut gemacht.

5-Als Teil des Vorteils von Angular2+ sind Sie jetzt berechtigt, gzip zu verwenden, nur für den Fall, dass Sie vorher nicht wussten, wie man es benutzt, jetzt, da Angular riesig ist, werden Sie es besser lernen :) Also los geht's, sie verkaufen gziping als Option zur Optimierung von Angular2-Code :)

@xe4me Bitte halten Sie die Diskussion in diesem Thread für das vorliegende Problem relevant, anstatt nur eine allgemeine Tirade gegen das Framework.

build:dev in https://github.com/AngularClass/angular2-webpack-starter konvertiert automatisch einen String in ein String-Array, um einer Funktionsdefinition zu entsprechen, build:aot zeigt den Fehler. Während der Entwicklung scheinen häufige AOT-Builds erforderlich zu sein.

Ich habe das gleiche Problem, und ich habe eine Lösung gefunden, vielleicht funktioniert es auch bei dir.

Mein Szenario war folgendes:

Ich habe eine MapPipes.ts, die zwei Pipes enthält.

Eine der Pipes wurde in meinem Modul verwendet, die andere nicht. Daher habe ich die zweite im "declaration:"-Teil meines @NgModule- Dekorators nicht registriert. Das Problem trat in dieser Sekunde auf.

Ich habe das auch registriert (obwohl es nicht verwendet wurde), und jetzt funktioniert es.

Mein Vorschlag ist, den Angular-Compiler so zu ändern, dass er versucht, Module nur für die wirklich verwendeten Angular-Entities zu finden.

Ich habe diesen Fehler mit einer abstrakten Klasse erhalten, die extends NgClass . Das Entfernen der Vererbung scheint dieses Problem zu beheben, verursacht aber offensichtlich andere Probleme.

@DzmitryShylovich @kirjai dies ist nur ein Problem mit TestComponents in einer Spezifikationsdatei, wenn Sie sie exportieren. Und da sie normalerweise nur innerhalb derselben Datei verwendet werden sollten, müssen sie nicht exportiert werden. Problem für mich gelöst.

Ehrlich gesagt, das ist lächerlich, ich habe wirklich nichts anderes dazu zu sagen, als die Tatsache, dass ich viele Stunden darin bin und immer noch nicht in der Lage bin, etwas zu bekommen, das unter JIT funktioniert, das mit AOT arbeitet (ich sollte klar sein, dass dies nur eine davon ist etwa ein halbes Dutzend Ausgaben bisher).

@cwmrowe das ist in Ordnung, aber was ist, wenn Sie eine haben, die in mehreren Spezifikationsdateien wiederverwendet wird? Das scheint kaputt zu sein, um ehrlich zu sein.

In meinem Fall habe ich an zwei verschiedenen Projekten in derselben Angular 2-Kernanwendung gearbeitet. Ich habe 2 Ordner, die nach unseren Kunden benannt sind, sagen wir some-domain.com und some-other-domain.com . Die App ist für die beiden Projekte genau gleich und unterscheidet sich nur ein wenig im Design und einigen kleineren benutzerdefinierten Komponenten. Heute muss ich die App für Client A kompilieren, und später möchte ich für Client B kompilieren. Im Code ist es so einfach wie 1 Codezeile für mich zu ändern:

import {CustomModules} from './some-domain.com';
// import {CustomModules} from './some-other-domain.com';

Ich entkommentiere einfach die Domain, die ich auch kompilieren möchte, und es funktioniert.

Wir haben das gleiche Problem mit Vererbung und abstrakten Klassen und wir haben keine Lösung gefunden. Wir haben einige Komponenten, die eine abstrakte Komponente erweitern. In JIT funktioniert alles super, aber in AOT können die Module für abstrakte Komponenten nicht gefunden werden und es ist nicht möglich, abstrakte Komponenten in einem Modul zu deklarieren.

Derzeit haben wir keine andere Lösung, als oop-Entwurfsmuster zu vermeiden und redundanten Code zu verwenden.

@jabaa Entfernen Sie die @Component -Anmerkung aus Ihrer abstrakten Klasse

@DzmitryShylovich Wenn ich @Component entferne, wird der Konstruktor nicht geerbt. Ich muss alle Injektionen in alle Komponenten anstelle der abstrakten Komponente injizieren. Das ist redundanter Code. Wenn ich den Konstruktor und die Dienste der abstrakten Klasse ändere, muss ich alle untergeordneten Komponenten anpassen.

Derzeit umgehen wir dies, indem wir alle abstrakten Methoden mit Dummy-Methoden implementieren und ein Dummy-Modul für alle abstrakten Komponenten erstellen. Aber dann könnte jemand vergessen, die Dummy-Methode zu überschreiben. Das ist alles nur eine Umgehung.

@jabaa welche Version verwendest du? Der Konstruktor sollte unabhängig von @Component geerbt werden.

@bigjetplane Ich bin mir nicht sicher, wo das Problem liegt, aber wenn ich @Component entferne, erhalte ich eine Fehlermeldung, dass die Abhängigkeiten für die Komponente nicht gefunden werden konnten. Soweit ich weiß, funktioniert DI nur für Klassen mit Angular-Dekorateuren. Wenn ich also die Dekorateure entferne, werden die Abhängigkeiten nicht injiziert. Wir verwenden Angular 4.

@jabaa ist es mit jit oder aot oder beidem gebrochen?

@bigjetplane Hier ist Plunker mit dem Problem. Es gibt eine abstrakte Klasse mit Dekorateur und alles funktioniert in Jit. Wenn Sie den Decorator aus der abstrakten Klasse entfernen, kann die App nicht gerendert werden, da nicht alle Abhängigkeiten geladen werden konnten: Can't resolve all parameters for App: (?).

Das ist unser Anwendungsfall. Wir haben eine abstrakte Klasse mit Konstruktor und Injects. Wir wollen nur einige abstrakte Methoden in den untergeordneten Komponenten überschreiben

Das angegebene Beispiel funktioniert nicht in aot. Der Unterschied zwischen aot und jit ist für uns ein großes Problem. Wir entwickeln mit jit. Der Produktionsaufbau erfolgt mit aot. Also entwickeln wir eine Woche mit Jit ohne Fehler und Warnungen und nach der Woche wollen wir einen Produktions-Build und bekommen viele Fehler aus dem Nichts. Ich bevorzuge einen Schalter für Jit, wo ich aot Fehler aktivieren kann. Ein Jit-Build benötigt 10-20 Sekunden. Ein Aot-Build benötigt 25 Minuten.

@tbosch Gibt es ein Wort, um dies in eine Warnung zu ändern? Es scheint, dass sich seit meinem letzten Besuch einige andere mit ihren eigenen Anekdoten zu Wort gemeldet haben, und ich habe mich gefragt, ob Sie uns ein Update geben könnten.

Danke!

Ich habe auch das gleiche Problem.

In meinem Fall habe ich an zwei verschiedenen Projekten gearbeitet, aber die gemeinsamen Komponenten durch ein internes Winkelbibliotheksprojekt eingeschlossen, das als Abhängigkeit in package.json hinzugefügt wurde.

Da es sich um ein Bibliotheksprojekt handelt, geben die nicht verwendeten Komponenten aus dem Komponenten-Repository den folgenden Fehler aus, wenn ein AOT-Produkt-Build kompiliert wird.

ERROR in Cannot determine the module for class FullPageErrorComponent in C:/users/amra6003/projects/git/refadmintoolui/n ode_modules/refcommonui/src/app/component-library/error/error.component.ts! Cannot determine the module for class SelectCountryComponent in C:/users/amra6003/projects/git/refadmintoolui/node_modul es/refcommonui/src/app/component-library/select-country/select-country.component.ts! Cannot determine the module for class DateRangeSelectorComponent in C:/users/amra6003/projects/git/refadmintoolui/node_m odules/refcommonui/src/app/component-library/date-range-selector/date-range-selector.component.ts!

Sieht so aus, als müsste ich für jede Komponente ein Modul erstellen und verwenden :(

Jede Lösung für dieses Problem wird sehr helfen.

Auch hier hoffe ich auf Abhilfe. Anscheinend ist die Verwendung von Stub-Komponenten zum Testen von den Angular-Entwicklern beabsichtigt - daher muss es auch möglich sein, sie sauber aus dem Build auszuschließen. Im Moment verwende ich die von gestj vorgeschlagene Problemumgehung (Definieren eines gefälschten Moduls, in dem die Stub-Komponente deklariert ist).

Wenn Sie also Stub-Komponenten zum Testen verwenden, möchten Sie Ihre Komponente mit dem Suffix spec.ts benennen, z. B. whatever.component.spec.ts . Auf diese Weise ignoriert tsc diese Dateien (da sie in Ihrer tsconfig ausgeschlossen sind) und wird daher auch von ngc ignoriert.

BEARBEITEN: Es stellt sich heraus, dass dies ein anderer Fehler ist, der auf einen Fehler in ngtools/webpack zurückzuführen ist. Dieses Ticket wurde hier geöffnet: https://github.com/angular/angular-cli/issues/6228


Neuer Spaß an dieser Front für mein Unternehmen. Bei einem kürzlichen Versuch, unsere Systeme auf v2.4.10 zu aktualisieren, endete ich mit ein paar Dutzend Fehlern dieser Art:

ModuleNotFoundError: Module not found: Error: Can't resolve '../../../../../../../../$_gendir/src/components/spinner/component.ngfactory'

Es scheint alle Komponenten in unserer gemeinsam genutzten Bibliothek zu protokollieren, die nicht von der aktuellen Anwendung verwendet werden. Dies ähnelt auf unheimliche Weise dem Fehler, für den ich das Ticket ursprünglich geöffnet habe.

Ich bin mir nicht sicher, was wir sonst dagegen tun können. Wir haben versucht, jede Komponente, die wir benötigen, direkt aus der Shared Lib zu adressieren (keine index.ts -Dateien zu verwenden, da diese scheinbar jede im Index referenzierte Datei einlesen) und alle Shared Libs in node_modules zu verschieben.

Warum muss der Compiler über jede eckige Komponente in meinem Ordner node_modules Bescheid wissen? Selbst wenn es sie lesen muss, um seine Karte zu erstellen, sollte es sich nicht darum kümmern, ob sie ein Modul haben oder nicht!

@swimadude66 , ja, wir sind bei der Arbeit mit unserer https://github.com/WealthBar/a2d3-Bibliothek darauf gestoßen. Obwohl sie keine Vorlagenkomponenten (nur Anweisungen) bereitstellt, muss die Bibliothek dennoch mit dem AoT-Compiler erstellt werden, oder sie funktioniert nicht mit AoT-Builds, wenn sie verwendet wird.

@chrisnicola Sie sagen, dass die Bibliothek vor der Veröffentlichung mit AoT vorkompiliert werden muss? denn das würde bedeuten, dass die Bibliothek ihre eigenen Module hat, was wirklich kontraintuitiv erscheint. So wie sie ist, besteht die Bibliothek aus unkompilierten ts-Dateien, die wir wie jede andere Datei in unser Projekt ziehen. Das Ganze wird dann mit dem Plugin @ngtools/webpack zu webpack kompiliert.

Es ist erwähnenswert, dass sogar der ursprüngliche Fehler für dieses Ticket auf unserer Seite bis v2.1.1 "behoben" wurde, indem einfach alle Verweise auf index.ts-Dateien entfernt wurden. Dieser Fix scheint für v2.4.10 nicht mehr zu funktionieren.

Ah, verstehe, ja, ich habe dein Problem falsch verstanden. Sie ziehen hier keine vorkompilierte gemeinsam genutzte Bibliothek über NPM ein, Sie haben eine lokale TS-Bibliothek in Ihrem Projekt. Verstehe ich das jetzt richtig?

Ich stimme zu, dass es "einfach funktionieren" sollte, und Sie haben Recht, es klingt definitiv nach dem gleichen Problem, bei dem Komponenten gefunden werden, die kein Modul in der Anwendung haben. Eine mögliche Lösung wäre die Verwendung eines AoT-Build-spezifischen tsconfig.json , das die Dateien und Ordner ausschließt, die für den AoT-Build nicht benötigt werden.

Ich habe es geschafft, alle unsere Probleme im Zusammenhang mit diesem Fehler zu lösen.
Das Problem (und die Lösung) tritt beim Exportieren auf.

Wir hatten eine Komponente, die nur zum Testen verwendet wurde. Es wurde aus einer anderen Datei exportiert, damit es wiederverwendet werden konnte – dies verursachte Probleme beim Ausführen unseres i18n-Ziels.

Um es zu lösen, haben wir gerade ein Modul deklariert (stellen Sie sicher, dass Sie es auch exportieren):

@NgModule({ declarations: [MyUnusedComponent] })
export class IgnoreModule {}

Unsere andere Komponente, die einen Fehler verursachte, war eine unbenutzte Komponente, die i18n gehackt hat.
Es wurde exportiert, um vom i18n-Tool aufgenommen zu werden, aber das verursachte den gleichen Fehler wie die andere Komponente.

@Component({
    template: `
        <div i18n="some context@<strong i="13">@some</strong> key">some text to be translated</div>
    `
})
export class LocalisationComponent {}

Wieder mit der IgnoreModule-Technik konnten wir es leicht umgehen.

@NgModule({ declarations: [LocalisationComponent] })
export class IgnoreModule {}

@UtopianStorm das ist keine Lösung. Es wurde oben erwähnt, dass ein „UnusedModule“ nicht nur schwer zu skalieren ist, sondern auch ein ganzes Modul aus Quelldateien erstellt, das nicht in das Distributionspaket aufgenommen werden sollte.

@Phmager Haben Sie jemals eine Problemumgehung für das Problem mit der abstrakten Komponente gefunden? Ich reiße mir die Haare aus.

@ Swimmadude66 Es ist keine Lösung in dem Sinne, dass es definitiv eine Problemumgehung ist - aber es überwindet den Fehler.
Ich bin mir nicht sicher, wie schwierig es wäre, zu skalieren, da die Technik jedes Mal angewendet werden kann, wenn das Problem auftritt.

Es wird Ihr Distributionspaket überladen, aber spielt das eine Rolle? Vom Zustand von Angular aus ging ich davon aus, dass es bereits mit unseren Spezifikationsdateien übersät wäre.
Auf jeden Fall ist es ein viel saubererer Ansatz, als direkt in die Eingeweide des node_modules-Ordners zu greifen, stimmst du nicht zu?

Zumindest aus dem Anwendungsfall, für den ich das Ticket ursprünglich geöffnet habe, ist es nicht einmal eine praktikable Problemumgehung. Es ist nicht für jedes Partnerteam machbar, eine Liste ungenutzter gemeinsam genutzter Komponenten zu führen.

Darüber hinaus ist das Versenden von im Wesentlichen 2 vollständigen Apps, nur weil der Compiler zu streng ist, ein Kompromiss, den ich nicht eingehen möchte. Angular ist bereits ziemlich groß, und ich kann es nicht rechtfertigen, ein ganzes Modul mit unbenutzten Komponenten zu versenden, nur um ihren rechthaberischen Compiler glücklich zu machen.

@schwimmmadude66 Ich verstehe. Wenn Sie der Meinung sind, dass das Hinzufügen eines weiteren Moduls einen so großen Unterschied macht, schaue ich es mir besser noch einmal selbst an - denn ich habe nicht dafür plädiert, nur ein unbenutztes Modul für das gesamte Projekt zu erstellen, sondern ein Modul für jede einzelne Komponente, die ich freigeben musste vom zu strengen Compiler - möglicherweise dusins.

Es ist erwähnenswert, dass unsere gemeinsam genutzte Codebasis ziemlich groß ist, sodass ein unbenutztes Modul bei weitem das größte Modul in der App wäre. Unsere Situation ist nicht 100% typisch, aber meiner Meinung nach noch im Rahmen des Zumutbaren.

Ehrlich gesagt, nachdem wir 5 Monate lang beobachtet haben, wie dieses Ticket nirgendwo hingeht, prüfen wir andere Optionen, einschließlich des einfachen Tötens unseres gemeinsamen Code-Repos

Ich stehe vor genau dem gleichen Problem wie du, @swimmadude66 . Dass dies keine unterdrückbare Warnung ist, ist lächerlich.

Liebes Angular-Team, können Sie etwas dagegen tun?

@DzmitryShylovich Wie schließe ich eine mock.ts -Datei aus, die ich nicht verwende? Ich habe versucht, es in tsconfig.app.json , tsconfig.json und tsconfig.ng-cli.json einzufügen, und nichts schien zu funktionieren.

Wir stehen vor dem gleichen Problem mit genau dem gleichen Anwendungsfall – wir verwenden Rollup, sodass unbenutzte Komponenten es nicht einmal in das ultimative Bundle schaffen.

Bitte unterdrücken Sie das! Es ist ein großes Ärgernis und stoppt die Arbeit.

Ich bin gerade auch darauf gestoßen, so verdammt frustrierend.

@mlakmal und andere, die Fehler bei Code wie bekommen

export class CustomGlobalModalComponent extends AppGlobalModalComponent {}

Entfernen Sie die Anmerkung @Component aus AppGlobalModalComponent oder deklarieren Sie AppGlobalModalComponent (falls verwendbar) in NgModule

Ich habe eine Mock-Direktive erstellt, um sie in meinen Tests zu verwenden. Und erhalten Sie dieses Problem mit der AOT-Kompilierung. Ich möchte diese Scheindirektive nicht in einfache Module importieren. Bitte beheben Sie dies.

Ich frage mich, ob das „freq1: low“-Tag zu diesem Thema auf die Tatsache zurückzuführen ist, dass AoT eine so spektakuläre Nervensäge ist, um zum Laufen zu kommen, dass sich die Leute nicht einmal darum kümmern? Es ist ein bisschen unglaublich, dass ein so einfaches, aber schmerzhaftes Problem im Wesentlichen kein Feedback von den wichtigsten Mitwirkenden von Angular erhalten hat.

Wie auch immer, es gibt eine Möglichkeit, Dateien auszuschließen, die nicht ausdrücklich erwähnt wurden. Wenn Sie ein Benennungsmuster haben (z. B. .spec.ts , .abstract.ts , .stfu-aot.ts ), können Sie eine separate tsconfig.json -Datei für AoT erstellen und diese stattdessen verwenden: ngc -p tsconfig-aot.json . In dieser Datei können Sie die "exclude": ["./app/**/*.stfu-aot.ts"] verwenden, um die Dateien auszuschließen. Es ist nervig, aber es sollte funktionieren.

Bearbeiten: Das Obige scheint nicht mit abstract Klassen zu funktionieren, die von einer Komponente erben. Yay :(

Ich bin gerade auch darauf gestoßen, also verdammt frustrierend. Beim Erstellen von aot kann eine gemeinsame Komponente nicht in einer anderen App geteilt werden

Einige der häufigsten Fälle für dieses Problem , vermeiden Sie es, @Component zu Ihrer Dienstklasse hinzuzufügen:

// just remove this 
@Component({
    providers: []
});
@Injectable()
export class serviceClass {}

Ich habe ein Szenario, in dem ich einen Dienst in einen Dienst einfüge. Auf den ersten Blick scheint es einfach zu implementieren zu sein, fügen Sie einfach @Component hinzu. Daher sollten die Angular-Dokumente aktualisiert werden, um diese Lösung für komplexe Dienste anzuzeigen: Um dieses Problem zu beheben, habe ich @Component entfernt. Im Konstruktor des Dienstes habe ich hinzugefügt:
constructor(@Inject(ExampleService) private exampleService: ExampleService)

Sie müssen keinem Dienst @Component() decorator hinzufügen. Nur @Injectable()

FWIW Ich habe ein MockXYZComponent , das XYZComponent eine App-Komponente erweitert, aber nur in Spezifikationen verwendet wird (hat denselben Selektor und kann daher nicht in AppModule importiert werden).

Ist dies kein gültiger Anwendungsfall?

@alastair-todd Ich bin mir nicht sicher, ob ich verstehe, was du meinst. Wenn Sie Komponente als Komponente verwenden, fügen Sie @Component() Decorator hinzu. Wenn Sie eine Komponente als Basis verwenden - nur um davon zu erben, aber nicht als Komponente, müssen Sie keinen Decorator verwenden - sondern nur erben und Decorator für "Nachfolger" verwenden.
Über Unit-Tests - ich kann nicht antworten, wahrscheinlich müssen Sie ein spezielles TestModul erstellen? Im Moment führe ich keine Unit-Tests durch.

@tytskyi Ich habe verstanden, dass die Decorator-Vererbung nicht unterstützt wird. Hat sich das kürzlich geändert?

Der Anwendungsfall besteht darin, eine Unterkomponente wie unten zu simulieren. Beide benötigen die Direktive @Component , um den Selektor aufzunehmen.

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                AppModule
            ]
        }).overrideModule(AppModule, {
            remove: {
                declarations: [SelectionToolComponent]
            },
            add: {
                declarations: [MockSelectionToolComponent]
            }
        }).compileComponents();

Dies erzeugt jedoch den OP AOT-Kompilierungsfehler.

Mein Punkt ist, dass dies ein gültiger Anwendungsfall ist, in diesem Fall ist die AOT-Kompilierung übereifrig und/oder ignoriert Spezifikationen als Teil des Projekts.

Vielleicht hilft meine Lösung jemandem: Ich habe gerade ein Dummy-Modul erstellt, das alle Mock-Komponenten deklariert. Dieses Modul wird von nichts importiert – es hält nur den AoT-Compiler bei Laune. Folglich ist keine der Scheinkomponenten Teil des kompilierten Codes. Nicht ideal, aber Problem gelöst.

Ich würde gerne von einer besseren Lösung hören.

Das ist so seltsam und peinlich, dass diese Ausgabe im Dezember 2016 eröffnet wurde und immer noch dieses Problem hat. Ich habe die Struktur meiner gesamten App konvertiert, um eine OT-Kompilierung zu verwenden. Ich habe 4 Module, die faul geladen sind, und über 60 Komponenten. Der Compiler beschwert sich nur über ein paar Komponenten (wie der Fehler vermuten lässt), von denen ich sicher bin, dass sie bereits Teil der Deklarationen eines der faul geladenen Module sind, was mir irgendwie seltsam vorkommt.

Es gibt sogar Fehler bei Komponenten, die bereits Teil eines Moduls sind.

Gleicher Fehler

Der Compiler von Angular sucht nach dem Dateisatz, den Sie an tsconfig übergeben haben. Wenn Sie also Dateien von dort ausschließen, sollten sie von dieser Überprüfung ausgeschlossen werden.

Das ist echt nervig :(

@alastair-todd Entschuldigung, ich habe die Benachrichtigung von deiner Frage in unzähligen anderen Benachrichtigungen verloren. Du hast Recht -
Decorator-Vererbung wird nicht unterstützt.

Siehe Antwort von @robwormald

Der Compiler von Angular sucht nach dem Dateisatz, den Sie an tsconfig übergeben haben. Wenn Sie also Dateien von dort ausschließen, sollten sie von dieser Überprüfung ausgeschlossen werden.

Sie könnten also versuchen, Konventionen für Scheindateinamen zu treffen, wie zum Beispiel: selection-tool.component.mock.ts . Dann über ausschließen

"exclude": [
    //... other excludes
    "**/*.component.mock.ts"
]

aus Versehen auf den falschen Button geklickt, sorry!

+8 Monate und es ist immer noch ein Problem. Hier das gleiche Problem ERROR in Cannot determine the module for class PasoFooterComponent

Ich denke, es ist wichtig, dass die Angular-Entwickler diese Dateien ignorieren.

Wenn mir jemand Tipps geben kann, wo ich diesen Code finden kann, würde ich mich freuen
um es selbst zu reparieren. Das ist ein Ärgernis, das sehr nervig ist. Bin hinein gerannt
gestern wieder.

Wenn jemand denkt, dass dies ein Feature und kein Bug ist, wie wäre es, wenn wir eine Flagge haben
dafür?

Am Mittwoch, 9. August 2017 um 2:40 Uhr, Leonardo Vidal [email protected]
schrieb:

+8 Monate und es ist immer noch ein Problem. Gleiches Problem hier ERROR in Cannot
Bestimmen Sie das Modul für die Klasse PasoFooterComponent


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/angular/angular/issues/13590#issuecomment-321082545 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AEM6r7FOTLcicWJN3Oijw2pwKTLGL6cFks5sWM61gaJpZM4LSAwS
.

@samirotiv Hast du eine Reproduktion?
Wie @robwormald sagte

Der Compiler von Angular sucht nach dem Dateisatz, den Sie an tsconfig übergeben haben. Wenn Sie also Dateien von dort ausschließen, sollten sie von dieser Überprüfung ausgeschlossen werden.

Ich hatte das gleiche Problem, aber ich konnte es lösen. Ich habe mir gerade angesehen, wie ts zum Beispiel meine App transpiliert

"tsc": "rimraf out-tsc/app && tsc -p ./src/tsconfig.app.json",

Und mir ist aufgefallen, dass Typoskript meine faul geladenen Module nicht kompiliert hat, weil ich die tsconfig-Option "files" verwendet habe

Ich erhalte diesen Fehler in der abstrakten Klasse (ohne Dekorateure)

Ich bin kürzlich selbst auf dasselbe Problem gestoßen.

+1 zum Ändern des Fehlers in eine Warnung.

Scheint eine einfache Lösung zu sein. Warum die Verzögerung?

Dies ist eine Grundvoraussetzung - lassen Sie nicht referenzierte Dateien.
Diese Einschränkung ist bei größeren Projekten ein Problem. Bitte ändern Sie dies in Warnung.

Es gibt Fälle, in denen Sie ein Paket veröffentlichen, das verschiedene Versionen von Angular unterstützt. und vom Benutzer wird erwartet, dass er einen von ihnen auswählt.

Zum Beispiel ein Paket, das Dateien sowohl für HttpClient (Angular >= 4.3 Benutzer) als auch Http (Angular < 4.3 Benutzer) bereitstellt.

Derzeit kompiliert ngc entweder alle Dateien in einem Quellverzeichnis, egal ob Sie sie verwenden oder nicht! oder der Build schlägt fehl.

Was ich tat, war Folgendes:

Ich habe alle meine Stub-/Mock-Komponenten mit einer .mock.ts -Erweiterung gespeichert und das tsconfig.app.json -Array "exclude" wie folgt aktualisiert:

...
  "exclude": [
    "test.ts",
    "**/*.spec.ts",
    "**/*.mock.ts"
  ]
...

AOT überspringt jetzt die Kompilierung dieser Dateien

Wir machen eine npm-Bibliothek mit gemeinsamen Komponenten, die nicht alle auf einmal verwendet werden sollen, und sind sauer auf dieses Problem während der AoT-Kompilierung, verdammt ... Die einzige Lösung für atm besteht darin, eine Art von UnusedComponentsModule im Host-Projekt zu erstellen - einfach lächerlich! Benötigen Sie auch NO_ERRORS_SCHEMA oder es schwört auf andere Komponenten, die in Ihren nicht verwendeten Komponenten verwendet werden können, und wenn Sie sie deklarieren, stoßen Sie auf ein anderes Problem, bei dem Sie nicht dieselbe Komponente in zwei Modulen deklarieren können (bezogen auf # 10646).

Mein aktuelles Modul:

import {NgModule, NO_ERRORS_SCHEMA} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ReceiverPageComponent} from 'cb-web-platform';

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    ReceiverPageComponent
  ],
  schemas: [
    NO_ERRORS_SCHEMA // IMPORTANT: need that for AoT compilation
  ]
})
export class UnusedComponentsModule {
}

Das sollte wirklich eine Warnung sein. Ich versuche auch, eine Codebasis zu teilen, und stoße auf dieses Problem, dass Komponenten nicht Teil eines ngmodule sind.
Das Problem hier ist genau gleichbedeutend mit einer unbenutzten Variablen, die kein Fehler ist; höchstens eine Warnung.

Es ist einfach, wenn es Ihr Code ist. Wenn es sich um ein Problem mit einer NPM-Winkelbibliothek handelt (irgendein toter Code), dann ist es wirklich ein Ärgernis :)

Kann jemand erklären, warum es keine Warnung statt eines Fehlers sein kann?

In meinem Fall möchte ich nur Langs vorzugsweise aus Komponenten extrahieren, die mit ngModule verbunden sind, und diejenigen ignorieren, die dies nicht sind. Ich habe einen Haupt-App-Ordner mit Basiskomponenten und anwendungsspezifischen Ordnern, die manchmal Komponenten aus der Haupt-App überschreiben, wenn ich versuche, eine solche überschriebene Komponente mit xi18n zu extrahieren, es wird ein Cannot determine the module for class... -Fehler ausgegeben, der meiner Meinung nach einfach ignoriert und extrahiert werden könnte fortgesetzt werden könnte, ohne diese unbenutzte Komponente zu verwenden.

Eine Sache, die meiner Meinung nach ein Problem sein könnte, ist, dass ich immer noch diese Klasse verwende, die in dieser fehlerhaften Komponentendatei als Basis zum Erstellen der überschriebenen Komponente definiert ist, sodass sie kompiliert werden muss, aber ich brauche diese Komponente einfach nicht Anmerkungsursache, da Sie sie nicht in überschriebenen Komponenten verwenden können. Zumindest denke ich, dass Sie das nicht können, weil ich diese Anmerkungen in abgeleiteten Komponenten neu erstellen muss, damit sie funktionieren.

@Xesenix zumindest sollte es eine Option sein. Wie bestimmtModule = false / true. Jetzt sind es Bananen.

Ich kehre zurück am 01.11.2017.

Ich werde Ihre Nachricht nach meiner Rückkehr beantworten.
In dringenden Fällen senden Sie bitte eine Kopie Ihrer E-Mail für
technische Angelegenheiten an [email protected], ansonsten an
[email protected]. Ein anderer Mitarbeiter wird sich dann Ihrer E-Mail
annehmen.

Hinweis: Dies ist eine automatische Antwort auf Ihre Nachricht "Re:
[angular/angular] Angular2 AOT compilation - "Cannot determine the module
for class (... many components which are unused)" (#13590)" gesendet am
23.10.2017 08:13:17.

Diese ist die einzige Benachrichtigung, die Sie empfangen werden, während
diese Person abwesend ist.

Wie ist das fast 1 Jahr später immer noch nicht behoben? Ich ziehe mir die Haare aus, um AOT zum Laufen zu bringen, aber dieses Problem bringt mich dazu, gegen eine Mauer zu stoßen.

Danke @rahul-sivalenka-wtc für die Lösung!
Ich konnte mein Problem erfolgreich lösen, indem ich "**/*.mock.ts" in meinem tsconfig.app.json ausschloss, wie Sie es beschreiben ❤️

Freut mich, dass ich helfen konnte 😊

Ich bin auch auf das Problem gestoßen. Aber für mich scheint ich den Pfad des Importierens von Dodule einfach falsch angegeben zu haben

irgendwelche Lösungen? (Modul für Komponente Winkel 5 kann nicht ermittelt werden)

https://stackoverflow.com/questions/47119135/cannot-determine-the-module-for-component-angular-5

Dies sollte wahrscheinlich von severity3: broken . Für diejenigen von uns mit mehreren Build-Zielen und polymorphen Abhängigkeiten (von denen viele Anwendungsfälle oben dargestellt wurden) verhindert dieses Problem, dass Builds ohne ein verrückt kompliziertes Build-Setup funktionieren.

schon eine gute Lösung für dieses Problem? Das IgnoreModule ist nur ein Workaround, aber keine wirklich gute Lösung für dieses Problem. Das Ändern des Fehlers in eine Warnung wäre großartig!

Unsere Lösung bestand darin, eine transform -Funktion zu @ngtools/webpack hinzuzufügen, die Dateien durch die Vorverarbeitung leitet, und ifdef Komponenten basierend auf verschiedenen Einstellungen zur Kompilierzeit einzufügen. Sehr, sehr hässlich, aber funktional.

Versuchen Sie, zuerst alle Winkelabhängigkeiten in app.module.ts zu importieren, und importieren Sie dann die Komponenten.

` ---------------- Abhängigkeitsmodule zuerst importieren -----------------------
{BrowserModule} aus '@angular/platform-browser' importieren;
importiere {CommonModule} aus "@angular/common";
importiere { NgModule } aus '@angular/core';
importiere { RouterModule, Routen } aus '@angular/router';
importiere { HttpModule } von '@angular/http';
importiere { ReactiveFormsModule } aus '@angular/forms';
importiere { BrowserAnimationsModule } aus '@angular/platform-browser/animations';

-------------Dann Dienstmodule importieren ------------------------

Importiere { ApplyFormPostService } aus './Services/apply-form-post.service';
import { NavBarColorService } from './Services/nav-bar-color.service';

----------------------- Komponentenmodule abschließend importieren ----------------------- -

importiere { AppComponent } aus './app.component';
importiere { HeaderComponent } aus './components/header/header.component';
importiere {Karrierekomponente} aus './components/career/career.component';
import { HomeComponent } from './Components/home/home.component';`

Irgendwie löste dies den AOT-Kompilierungsfehler, der das Modul für die Klasse --- im Produktionsmodus auslöste

@KarthikSamyak In dieser Ausgabe geht es nicht um Leute, die Kurse haben, die in einem Modul enthalten sein SOLLTEN. Hier geht es um diejenigen von uns mit Komponentenbibliotheken, die bewusst von allen Modulen ausgeschlossen sind. Sie sind unbenutzter Code, der vom Compiler ignoriert werden sollte. Stattdessen gibt der Compiler einen nicht behebbaren Fehler aus, wenn er sie entdeckt.

Es sollte wirklich eine einfache Änderung sein, diesen Fehler in eine Warnung umzuwandeln, aber aus irgendeinem Grund hat es ÜBER EIN JAHR gedauert und wurde kürzlich auf der Roadmap von pri_col1 nach pri_col2 verschoben.

Ich bin zunehmend frustriert über das Angular-Team, weil es auf dieses Problem überhaupt nicht reagiert. Unser Unternehmen gab schließlich die Verwendung von Komponentenbibliotheken vollständig auf und entschied sich stattdessen dafür, Dateien manuell hineinzukopieren. Dies ist alles andere als ideal, da wir jetzt Probleme mit nahezu identischen, aber nicht gemeinsam genutzten Komponenten haben.

Angular-Team, wenn Sie diese Ausgabe überhaupt noch lesen, fügen Sie bitte einfach eine Compiler-Einstellung für „ignoreUnusedComponents“ hinzu und lassen Sie uns mit der Verwendung dieses Frameworks fortfahren.

Ok, ich habe den Ort gefunden https://github.com/angular/angular/blob/master/packages/compiler/src/aot/compiler.ts#L605 @tbosch hey, kannst du hier helfen und sagen, wie man das macht richtig gewarnt werden? Ich kann keine Warnungen in diesem AoT-Compiler sehen, nur Fehler. Die Compiler-Option kann wie oben vorgeschlagen hinzugefügt werden.

Dieses Problem ist bei komplexen Projekten ein Problem. Mein besonderer Fall ist https://github.com/angular/angular/issues/13590#issuecomment -331820496

Unser Anwendungsfall ist derselbe. Wir möchten eine Bibliothek von Modulen/Komponenten haben, um Apps wirklich einfach zu erstellen und die Möglichkeit zu haben, ungerade bei Bedarf zu ersetzen/erweitern.

Wir haben auch Probleme in der anderen Richtung: Wenn wir 1x-Komponente in einem Modul ersetzen möchten, erstellen wir ein neues Modul und importieren die Komponenten, die wir noch wollen:

import { HeaderComponent, SidebarComponent } from '@mylibs/layout';
import { FooterComponent } from './footer.component';

@NgModule({ declarations: [ HeaderComponent, SidebarComponent, FooterComponent ] })
export class MyLayoutModule { }

@NgModule({ imports: [ MyLayoutModule ] })
export class AppModule { }

Der Fehler lautet: „HeaderComponent ist in 2 Modulen deklariert: lib/module.ts und app/module.ts
Stattdessen eine Warnung zu sein, würde uns zumindest erlauben, voranzukommen :(

Gerade festgestellt - Happy Birthday zu dieser Ausgabe :)

Ein Jahr später, und wir können dies IMMER NOCH nicht in eine Warnung ändern. Lächerlich.

Buchstäblich gerade auch auf dieses Problem gestoßen. Der Compiler versucht, einen Mock einzufügen, der nur in Tests verwendet wird, und schlägt fehl, da er nicht Teil des Hauptmoduls ist. Wenn es weiß, dass es die Datei nicht benötigt, sollte es höchstens eine Warnung sein.

Bitte beheben Sie dies. Machen Sie es zu einer Warnung!
Meine allgemeine Erfahrung mit dem eckigen 5-aot-Build ist weniger als hervorragend.

Nach einigen Diskussionen https://gitter.im/angular/angular?at=5a551f565a9ebe4f756843b2 kamen wir zu dem Schluss, dass wir eine Komponente pro Modul erstellen müssen, da das Modul anscheinend nur ein Kompilierungskontext ist und keine Möglichkeit, Dinge zusammen zu sammeln. .

Das nimmt die Größe eines Geschichtsbuches ein.

@Xesenix ... der Kontext und die Organisation sind 2 Teile des Ganzen.

Nur für den Fall, dass jemand immer noch damit feststeckt, können Sie dieses Skript als Workaround als Postinstall-Skript ausführen lassen

const replace = require('replace-in-file');
const filesToFix = [
    {
        files: 'node_modules/@angular/compiler/esm2015/compiler.js',
        from: ['throw syntaxError(messages.join(\'\\n\'));'],
                // Actually this does nothing , just leave it blank should do
        to: [`console.warn(\'Angular compiler warning\');\n\t\tconsole.warn(messages.join(\'\\n\'));`]
    }
]

filesToFix.forEach((i) => {
    try {

        const changes = replace.sync(i);
        if (changes.length > 0) {
            console.log('Modified files:', changes.join(', '));
        }
    }
    catch (error) {
        console.error('Error occurred:', error);
    }
});

Der Angle-Compiler verwendet die Ausgabe von tsconfig, also ändern Sie _tsconfig.app.json_ , um die Dateien auszuschließen, die Sie nicht einschließen möchten
z.B
"exclude": [ "test.ts", "**/*.spec.ts", "**/*.mock.component.ts", ]

@andela-andrewmakenzi das wurde schon früher vorgeschlagen, weiter oben in diesem gigantischen Chat (absolut keine Schande, das Ganze nicht durchzulesen). Es treten jedoch Probleme auf, wenn Sie von einer Komponente in einer Bibliothek abhängen, die Barrel-Dateien (index.ts) verwendet. Wenn Sie eine Komponente aus einer Barrel-Datei importieren, versucht der Compiler, alle Komponenten zu laden, auf die in dieser Barrel-Datei verwiesen wird, und beschwert sich, dass sie sich nicht in einem Modul befinden. Dies macht es schwierig, wiederverwendbare Komponentenbibliotheken zu packen, was im Grunde genommen der springende Punkt der Komponentenarchitektur ist.

Ihre Lösung funktioniert hervorragend für Personen, die Scheinkomponenten haben und diesen Fehler erhalten, wenn sie keine Tests ausführen. Aber wenn Ihre Organisation (wie meine) versucht, eine gemeinsame Komponentenbibliothek zu erstellen und nur die einzufügen, die wir für ein bestimmtes Projekt benötigen, wird Ihnen der Ausschluss von TSC leider nicht helfen.

@andela-andrewmakenzi: Ihr Vorschlag scheint vorerst zu helfen, das Problem zuvor ist, dass ich eine Komponente für Komponententests als ( Ich möchte es nicht einmal in meiner Projektion haben ) Vielleicht wurde dies in späteren Versionen von Angular irgendwie behoben, denke ich :)

Aber mein Fall war, dass ich viele neue Komponenten habe, die nicht einmal in NgModule referenziert wurden, also müssen wir vorerst eine Namenskonvention dafür haben und sie in tsconfig.json ausschließen, was vorerst nicht sehr angenehm ist

Das ist wirklich lächerlich. Wir haben ein gemeinsam genutztes NPM-Modul, das einige Pipes/Direktiven exportiert, und wenn Sie nicht ALLE importieren, schlägt es mit diesem dummen Fehler fehl. Es sollte wirklich in eine Warnung geändert werden und es sollte die Kompilierung nicht unterbrechen.

Meiner Meinung nach sollte jede Komponente in einem eigenen NgModule stehen. Es ist nicht so beängstigend, für jede Komponente ein weiteres NgModule zu erstellen. (Wie das, was @angular/material getan hat)

Ich denke, dass es wirklich ein virtuelles Problem ist. Wir sehen auch keinen Grund, etwas nur halb herum zu haben. Kein NgModule , kein Paket, nicht außerhalb des App-Baums ... etwas, das wie toter Code aussieht.

Mit dem neuen @angular/cli (1.7.0+) umgeht sogar IgnoreModule dieses Problem irgendwie nicht.

Meiner Meinung nach sollte jede Komponente in einem eigenen NgModule sein

Versuchen Sie überhaupt, Unit-Tests zu schreiben? Dieser Fehler macht das Erstellen von Testhelfern ziemlich problematisch.

@sarunint In Anwendungen in Unternehmensgröße wie der, für die ich dieses Ticket ursprünglich geöffnet habe, wären das Hunderte von Modulen mit sehr komplizierten Importen, um abhängige Anweisungen und Komponenten zu handhaben. Dies hat eine sehr einfache Lösung: Wenn der Compiler kein Modul für eine Komponente finden kann, geben Sie eine Warnung aus und entfernen Sie es im Tree-Shaking.

Der wahre Grund, warum dies so ärgerlich ist, ist die Tatsache, dass Fassfeilen eher zu einer Gefahr als zu einem Segen werden. Es ist praktisch, Ihre Importe zu zentralisieren, aber nicht, wenn Sie sich dazu verpflichten, jede einzelne exportierte Komponente in jede App aufzunehmen, die Ihre Bibliothek verwendet.

@dborisenkowork Ich bin mir nicht sicher, ob Sie es nicht gesehen haben (oder ob es für Ihren Anwendungsfall nicht funktioniert), aber die von @rahul-sivalenka-wtc bereitgestellte Lösung funktioniert perfekt.

Ist jemand kürzlich von Winkel 4 zu Winkel 5 gewechselt und hat bemerkt, dass einige ihrer Komponenten, die tatsächlich in Modulen deklariert werden, diesen Fehler auslösen?

@novologic-clay welcher Fehler? Der Thread ist lang, beziehen Sie sich auf den ursprünglichen Fehler
Angular2 AOT-Kompilierung - "Das Modul für die Klasse kann nicht bestimmt werden (... viele Komponenten, die nicht verwendet werden)" ?

@andela-andrewmakenzi Ja und nein. Es ist derselbe Fehler, der beim Kompilierungsversuch ausgegeben wird, aber die Komponente, über die er sich beschwert, ist höchstwahrscheinlich in einem Modul enthalten. Ich migriere von 4.3.6 auf 5.2.4, und ich habe diesen Fehler für diese bestimmte Komponente nicht erhalten, weil ich meine Version von Angular aktualisiert und eine AOT-Kompilierung auf 4.3.6 durchgeführt habe, kurz bevor ich mit der Migration als Rauchtest begonnen habe .

@novologic-clay kannst du deine Konsolenfehler teilen?

... das Endziel sollte die Verwendung der Option $ tsconfig.json "noUnusedLocals": true sein, die alles eliminiert, was nicht verwendet wird.

@andela-andrewmakenzi

ERROR in : Cannot determine the module for class InlineAddComponent in /Users/claygarland/CatalsytConnect/frontend/Talon/src/app/core/component/input/inline-add/inline-add.component.ts! Add InlineAddComponent to the NgModule to fix it.

Dies ist eine Unternehmensanwendung und es gibt Dutzende von Ebenen von Modulen und Importen, aber dies ist der Code, der die Komponente tatsächlich deklariert:

**COMPONENT:**
import {Component, Inject, Input} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
import {ActivatedRoute} from '@angular/router';
import {BaseForm} from '../../form/form/BaseForm';
import {FormDataService, FormDataServiceProvider} from '../../form/form/FormDataService';
import {BaseApi} from '../../../api/BaseApi';

@Component({
    selector: 'inline-add',
    templateUrl: './inline-add.component.html',
    styleUrls: ['./inline-add.component.scss'],
    providers: [
        FormDataServiceProvider
    ]
})
export class InlineAddComponent extends BaseForm {

    @Input() title = 'Entity';
    @Input() formName;

    protected service: BaseApi;

    constructor(
        protected route: ActivatedRoute,
        protected formDataService: FormDataService,
        public dialogRef: MatDialogRef<InlineAddComponent>,
        @Inject(MAT_DIALOG_DATA) public data: {
            form: string,
            title: string,
            service: BaseApi,
        },
    ) {
        super();
        this.title = data.title;
        this.formName = data.form;
        this.service = data.service;
    }

    submit() {
        super.onSubmit(res => {
            this.dialogRef.close(res.data[0]);
        });

    }

    onCancel() {
        this.dialogRef.close(false);
    }

}

**MODULE:**
import { NgModule } from '@angular/core';
import {SharedModule} from '../../../shared/shared.module';
import {InlineAddComponent} from './inline-add/inline-add.component';


@NgModule({
    imports: [
        SharedModule,
    ],
    declarations: [
        InlineAddComponent,
    ],
    exports: [
        InlineAddComponent,
    ],
    entryComponents: [
        InlineAddComponent,
    ]
})
export class FormInputsModule { }

Bemerkenswert ist auch, dass die Komponente einwandfrei funktioniert, wenn ich diese Anwendung in ng serve ausführe.

Gefälschte Komponenten, die von Tests vieler echter Komponenten verwendet werden, sollten nicht in einem Modul enthalten sein; Sie sind nur im TestBed der getesteten Komponenten enthalten.
Dieser Fehler ist dumm. Bitte lösen Sie das so, wie es in einem Jahr ist.

Entfernen Sie den "Export", damit ts ihn nicht zum Build bringt.

@tony-kaplan Sie können das nicht tun, wenn Sie noUnusedLocals in Ihrer tsconfig haben, noch wenn Sie den Code in Testfällen oder ähnlichem verwenden möchten.

Mein Gott.... wirklich, dass niemand aus dem Kernteam eine passende Lösung dafür gefunden hat?
Ich verwende im Moment die Option exclude , aber es ist immer noch eine vorübergehende Lösung. Mir fällt nichts ein, was für alle Situationen funktionieren würde ... aber ich brauche es wirklich ...

@gabrielalan Die einfache Lösung besteht darin, diesen Fehler in eine Warnung umzuwandeln. Die bessere Lösung besteht darin, ein Flag hinzuzufügen, mit dem Sie dies als Warnung oder Fehler behandeln können. Es ist nicht ein Mangel an Lösungen, es ist ein Mangel daran, eine von ihnen tatsächlich umzusetzen.

Oh Junge! Soviel zum Enterprise-Framework...

@atom-morgan, von welcher Problemumgehung sprichst du?

@netlander Dieser

Kann ich wirklich nichts gegen den Fehler „Das Modul für die Klasse DaterangepickerDirective kann nicht bestimmt werden“ tun?

Hilft mir auch jemand? Nach diesem Megazord-Post!

Ich stimme nicht zu, in der tsconfig.app.json neue Ausschlüsse zu dieser Richtlinie hinzuzufügen! Wie kann ich ohne dieses Problem mit --aot param kompilieren?

Mein Anwendungsfall https://github.com/angular/angular/issues/23475
Ich erstelle eine Validator-Bibliothek und möchte kein Modul für jede Validator-Direktive erstellen. Ich möchte nur in der Lage sein, Validator-Direktiven in ein npm-Paket zu bündeln, damit der Benutzer nur Validatoren installieren und importieren kann, die er für sein NgModul benötigt. Außerdem möchte ich kein Modul für alle Validatoren erstellen, da sie alle im endgültigen Paket gebündelt werden, was eine enorme Größenverschwendung darstellt.

Ich freue mich, PR zu erstellen, um das Problem zu beheben.

@anjmao , das ist dem Grund, warum ich das überhaupt geöffnet habe, unglaublich ähnlich. Als Problemumgehung für eine kleine Bibliothek haben wir festgestellt, dass dieser Fehler nicht auftritt, wenn Sie keine Barrel-Dateien (index.ts) verwenden. Es scheint, dass, wenn Sie 1 Komponente/Direktive aus einem Index importieren, versucht wird, ein Modul für alle anderen Exporte der Indexdatei zu finden.

Natürlich glaube ich immer noch, dass dies eine Warnung sein sollte, da Barrel-Dateien super praktisch sind. Wenn Ihr Anwendungsfall jedoch kein weiteres Jahr auf diesen Fix warten kann, können Sie ihn möglicherweise so umgehen.

Problemumgehung, die ich für meine gemeinsam genutzte Bibliothek von Komponenten/Direktiven/Pipes verwende: Erstellen Sie ein einfaches Dummy-Modul, das auf alle Klassendeklarationen verweist. Sie müssen dieses Modul nicht in Ihren echten Apps verwenden, es muss nur auf der Festplatte vorhanden sein. Ex:

import { NgModule } from '@angular/core';

@NgModule({
    imports: [],
    declarations: [
        MyComponent,
        MyPipe,
        MyDirective,
        ...
    ],
})
export class DummyModule {
}

Gibt es einen Grund, warum wir dieses Problem immer noch nicht behoben haben?

Ist die Lösung „Mach es eine Warnung“ nicht ausreichend? Kann ein Mitglied des Kernteams dazu etwas sagen?

In meinem Fall war alles in Ordnung mit NG 5, CLI und AOT. Aber nach dem Upgrade auf NG 6 erhalte ich einen ähnlichen Fehler für eine nicht verwendete Komponente. Tatsächlich wird die Komponente durch einen Dienst verwendet, der in die andere Komponente injiziert wird. Ich habe viele ähnliche Komponenten konstruiert und auf die gleiche Weise verwendet. Aber gerade ein Upgrade auf die neueste NG CLI 6.0 und 6.0.1 hat ein Problem

Und es stellte sich gerade heraus, dass ich in einer der Referenzen die Dateireferenz im falschen Fall habe. Ich habe eine index.ts, um alle Komponenten in dasselbe Verzeichnis zu exportieren. ich hatte
export * from './dateTimePicker.component'
während es hätte sein sollen:
export * aus './datetimePicker.component';

Anscheinend ist NG CLI 6 selbst unter Windows für die Groß- und Kleinschreibung eingeschränkter, während NG CLI 1.x etwas entspannter ist.
Offensichtlich ist eine solche Einschränkung gut und richtig, sodass die gleiche Codebasis unter Linux gut funktionieren könnte, das standardmäßig zwischen Groß- und Kleinschreibung unterscheidet.

Ein weiterer Anwendungsfall dafür:

Mit Typescript können Sie mehrere Auflösungspfade mit der Variablen paths in tsconfig.json . Ex:

{
    ...
    "paths": {
        "~src/*": ["src/*", "src-gen/*"]
    }
}

So können Sie Dinge wie diese importieren:

import { NgModule } from "@angular/core";
import { ExampleComponent } from "~src/example.component";

@NgModule({
    declarations: [
        ExampleComponent
    ],
})
export class ExampleModule {}

Wenn Sie eine Komponente in src-gen generieren, die der Entwickler "überschreiben" kann, indem er eine andere im Ordner src erstellt, tritt derselbe Fehler bei der (jetzt unbenutzten) Komponente in src-gen (das nicht gelöscht werden sollte, da es durch den Overrider erweitert werden könnte).

Ein weiterer möglicher Anwendungsfall:

Umgebungsspezifische Komponenten. Ich entferne sie für die Produktion.

const environmentComponents = production ? [] : [
  DevOnlyComponent,
];

@NgModule({
  declarations: [
    ...environmentComponents,
  ],
})
export class ExampleModule {
}

Ich habe es geschafft, alles andere mit umgebungsspezifischen Komponenten zum Laufen zu bringen, und das hält mich davon ab. 😪

Wir sind mit diesem Problem konfrontiert, wenn wir einen Mechanismus zur Build-Anpassung implementieren (Komponenten werden für verschiedene Angular-CLI-Projekte ausgetauscht), der dem von @tiagodws beschriebenen Szenario ziemlich ähnlich sieht (einschließlich der Erweiterung der ursprünglichen Komponente).

Gibt es zu diesem Thema ein Update / eine Meinung eines Kernteams?

Über ein Jahr, nachdem ich diese Ausgabe geöffnet habe, besteht mein neuer Ansatz darin, die Verwendung von Barrel-Dateien zu minimieren. Wenn Sie in Ihren Importen überall TS-Pfade wie ~components/button/component verwenden, werden nicht verwendete Importe ignoriert. Wenn auf diese nicht verwendete Komponente in einer Barrel-Datei verwiesen wird, wird sie ausgelöst.

Das ist für wiederverwendbare Bibliotheken immer noch nicht großartig, da Sie auf alle Bibliothekskomponenten mit längeren Pfaden zugreifen müssen, anstatt nur von dieser obersten Bibliotheksebene zu importieren. Warum, oh warum kann das nicht nur eine Warnung sein?

Dies scheint auch durch Tree Shaking (oder zumindest im Zusammenhang damit) unterstützt zu werden, bei dem jeder Code, der nicht ausdrücklich in einem Modul enthalten ist, aus dem endgültigen Paket ausgeschlossen wird.

Option ausschließen gilt nicht für eine Mock-Pipe:

@Pipe({ name: 'translate' })
export class MockTranslatePipe implements PipeTransform {
    transform(value: string): string {
        //Do stuff here, if you want
        return value;
    }
}

Meine tsconfig.app.json hat diese Datei ausgeschlossen:

"exclude": [
        "test.ts",
        "**/*.mock.ts",
        "**/*.spec.ts"
    ]

Wenn ich jedoch ng-xi18n --i18nFormat=xlf2 --outFile=./assets/i18n/messages.xlf ausführe, beschwert es sich immer noch:

Das Modul für die Klasse MockTranslatePipe in src/test/translate.service.mock.ts kann nicht ermittelt werden! Fügen Sie MockTranslatePipe zum NgModule hinzu, um es zu beheben.

Mein Problem war, dass ich durch Kopieren und Einfügen den Namen einer Klasse in 2 verschiedenen Komponenten hatte lol! Später derselbe Fehler, sich nicht darum zu kümmern. Gute Übung macht den Meister! trifft ...
Unterschrift: Satoshi Nakamoto: v

Ähnlich wie bei @yuezhizizhang habe ich dieses Problem immer noch, auch nachdem ich dem Pfad tsconfig.app.json exclude einen Glob für Mocks hinzugefügt habe.

Es ist schon fast ärgerlich, dass dies fast zwei Jahre nach dem ersten Ticket nicht gelöst wurde; Dies ist ein häufiger Anwendungsfall, bei dem es sich um BREAKING-Builds handelt. Beim Schreiben von Tests sollte der Entwickler idealerweise Mocks für Pipes, Dienste usw. erstellen, es sei denn. Wenn Sie sich dafür entscheiden, bricht Ihr Build zusammen. Wenn nicht, verweisen Ihre Spezifikationsdateien auf die realen Komponenten/Rohre/usw., was zu sehr eng gekoppelten Tests führt.

Könnte jemand aus dem Angular-Team bitte vorschlagen, wie man das umgehen kann? Ist die Erstellung eines Catch-All-Dummy-Moduls für Mocks wirklich die einzige Option? Das ist eher ein schlechter Hack als etwas, das wir als Best Practice akzeptieren sollten.

das Problem besteht weiterhin. Ich habe auch die Datei, in der ich den Build (abstrakte Klasse) überspringen möchte, zum Exclude -Abschnitt von tsconfig.app.json hinzugefügt und bekomme immer noch:

Das Modul für die Klasse MapElementBaseComponent in .../map-elements/map-element-base.component.ts kann nicht ermittelt werden! Fügen Sie MapElementBaseComponent dem NgModule hinzu, um es zu beheben.

Ich habe dieses Problem beseitigt, nachdem ich die Importe doppelt überprüft habe

ср, 14 нояб. 2018 г., 15:13 Daniel Groh [email protected] :

das Problem besteht weiterhin. Ich habe auch die Datei hinzugefügt, mit der ich den Build überspringen möchte
(abstrakte Klasse) zum Exclude -Abschnitt von tsconfig.app.json und I
immernoch bekommen:

Das Modul für die Klasse MapElementBaseComponent in kann nicht bestimmt werden
.../map-elements/map-element-base.component.ts! Fügen Sie MapElementBaseComponent hinzu
zum NgModule, um es zu beheben.


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/angular/angular/issues/13590#issuecomment-438641324 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AQb6kpWdkakUF8JVvea8Hy42tAnTKTuzks5uvAjvgaJpZM4LSAwS
.

Beim strikten TypeScript-Import von Angular in der AOT-Kompilierung nicht verwendete Komponenten aus einer Bibliothek und Lanchen dieses Fehlers ... Nicht verwendete Komponenten / Module überprüfen hat keinen Sinn ...

image

Durch das Löschen des Bibliotheksordners, in dem sich die nicht verwendeten Module und Komponenten befinden, startet die Anwendung im strikten Zustand - aber es ist sicherlich nicht sinnvoll, diesen Ordner manuell zu löschen

Dieser Fehler ist absolut lächerlich. Ich hatte ein Modul, das Komponenten in einem Objekt angab, wie folgt:

const landingComponents = {
    'landing-root': LandingComponent,
    'get-notified': GetNotifiedComponent,
    'typed-component': TypedComponent,
    'sticky-bar': StickyBarComponent,
};

dann habe ich versucht, das Modul mit declarations: Object.values(landingComponents) , entryComponents: Object.values(landingComponents) zu füttern.

Ratet mal ... der AOT-Compiler muss die in einem Array aufgelisteten Komponenten sehen ... andernfalls bekomme ich, wenn ich es auf andere Weise übergebe, dieses schreckliche "Das Modul für die Klasse kann nicht bestimmt werden".

So sehr ich Angular auch liebe, der AOT-Compiler wirkt wie eine chaotische Suppe magischer Beschwörungsformeln.

Es wurde ein paar Mal gesagt, aber die Lösung ist 1 Komponente pro Modul dafür und ich bin mir nicht sicher, ob Sie es von den PRs zu Angular bemerkt haben, aber dies wurde kürzlich zusammengeführt und könnte für dieses Thema von Interesse sein: https://github.com/ eckig/eckig/ziehen/27481

Diese Ausgabe wird heute 2 Jahre alt 🎉

Trotzdem kein Wort vom Kernteam darüber, warum dies nicht nur eine Warnung sein könnte.

@tiagodws lol wie lange hast du darauf gewartet das zu posten? Hast du eine Erinnerung eingestellt?

Nur ein FYI
Mein Problem war dasselbe wie https://github.com/angular/angular/issues/13590#issuecomment -389113560
Beim Import wird im AOT-Modus anscheinend zwischen Groß- und Kleinschreibung unterschieden

@peterdeme ... Bei JavaScript wird zwischen Groß- und Kleinschreibung unterschieden (und Pfade wie Zeichenfolgen gleich ... = Linux-basiert, nicht Windows).

Hey Leute, ich komme gerade noch einmal vorbei für eine verspätete Feier zum 2-jährigen Ausgabealter. Es gibt viele Diskussionen über mögliche Ursachen für Menschen, einschließlich der Abschnitte include und exclude von tsconfig.json , daher möchte ich nur klären, was das Grundproblem ist für diesen Faden.

Wenn Sie eine Bibliothek mit wiederverwendbaren Komponenten erstellen und Barrel-Dateien ( index.ts ) für einfachere Importe hinzufügen, wird der Angular-Compiler unterbrochen, wenn Sie eine davon verwenden. Dies liegt daran, dass sobald Sie etwas aus dieser Barreldatei importieren (z. B. @shared/components ), versucht, das Modul für JEDE EINZELNE KOMPONENTE zu finden. Selbst wenn Sie die gewünschten spezifischen Komponenten angeben (z. B. import { SharedToastComponent } from '@shared/components'; ), sucht der Compiler immer noch für jede einzelne exportierte Komponente nach dem Modul und gibt einen Fehler (keine Warnung) über die fehlenden Komponenten aus.

Offensichtlich gibt es Problemumgehungen.

  1. Verwenden Sie keine Barrel-Dateien mehr. Das wird schnell chaotisch, da jede Komponente vollständig spezifiziert werden muss
  2. Verwenden Sie ein ExtrasModule und verwenden Sie das Modul nirgendwo. Dies funktioniert gut für Leute, die Komponenten haben, die nur zum Testen benötigt werden, aber nicht so gut für Leute, die aus einer Komponentenbibliothek ziehen möchten

Da jedoch die Verwendung einer dieser Problemumgehungen nach dem Tree-Shaking zu genau demselben Ausgabecode führt, ist es offensichtlich, dass die anderen Komponenten nicht in einem verwendeten Modul enthalten sein MÜSSEN. Alles, worum ich bei diesem 2 Jahre alten Problem bitte, ist, diesen Fehler in eine angemessenere Warnung umzuwandeln. Macht Sinn, da die Kompilierung immer noch gelingen würde, wenn man sie fortsetzen ließe.

Wir hoffen, dass das Angular-Team 2019 etwas gegen dieses sehr alte, sehr lästige Problem unternehmen wird. 🤞

@swimmadude66 ... Sie haben nicht erwähnt, wie Sie ein echtes Lib-Modul erstellen und es über tsconfig.json zu einer Angular-App hinzufügen ... wie: "paths": {"ng-demo": ["./packages/ng-demo/src/index.ts"]} und es über Import wie import { DemoModule } from 'ng-demo'; verwenden

Einen Fehler auf jedem Komponenten-Stub zu haben, ist das Ärgerlichste. Jeder testet/schreibt Spezifikationen, richtig? Die Komponenten-Stub-Fehler sollten also alle betreffen. Ich sage nicht, dass das Fassproblem weniger nervig ist. Ich sage nur, dass nicht jeder die Fässer macht. Aber jeder sollte Spezifikationen machen. Das Spezifikationsproblem sollte also die größte Motivation für das Kernteam sein, dies zu beheben. Es ist derzeit mit "Häufigkeit niedrig" gekennzeichnet, sollte aber "Häufigkeit hoch" sein, da jeder, der Einheitentests durchführt, auf dieses Problem stoßen wird.

Dies ist nicht einmal in AOT konsistent. Angular CLI gibt keine Fehler aus, wenn es mit serve ausgeführt wird (was standardmäßig AOT verwendet), gibt jedoch Fehler aus, wenn es mit build ausgeführt wird.

Ich verstehe, dass dies nicht das Angular-CLI-Repo ist, aber das Verhalten in der Umgebung ist sicherlich seltsam.

Selbst mit der Problemumgehung, ein Mock-Modul zu erstellen, schlägt der „ng-Build“ jetzt fehl, wenn ein UI-Einheitentestautor vergisst, einem Mock-Modul eine einzelne Mock-Komponente hinzuzufügen.

Oben bedeutet, dass UI-Einheitentests derzeit ein Risikoelement für die CI/CD-Bereitstellungspipeline sind!

Wollen wir den Leuten in der Nahrungskette wirklich erklären müssen, dass Angular-Unit-Tester ganze Deployment-Builds mit einer einzigen trivialen Auslassung kaputt machen können? Nö. Leute, die Angular-Entwickler verwalten und Entscheidungen darüber treffen, welches Framework für das nächste Projekt verwendet werden soll, sollten sich über solche Dinge keine Gedanken machen.

Als Notlösung: Warum nicht einfach den Fehler, der in „ng build“ erscheint, informativer für Testautoren machen: d. h. zusätzlichen Text zum Effekt „wenn dies eine beim Testen verwendete Scheinkomponente ist: fügen Sie sie zu einem Scheinmodul hinzu Datei unter (dieser URL)"

Wie Ihre durchschnittlichen Einheitentests für benutzerfreundliche Angular-Entwickler hierher gekommen sind:

a) IMHO ist es eine DRY-Code-Praxis, eine "Hilfsdatei" zu erstellen, um Scheinkomponenten, Dienste usw. zu platzieren, die alle .spec-Dateien verwenden. Diese Vorgehensweise führt den Tester jedoch direkt in dieses Fehlerszenario.

b) Alle .spec-Dateien können diese „Hilfs“-Datei importieren, ohne dass ein „Mock-Modul“ benötigt wird, das keine Relevanz für den tatsächlichen Testcode hat. Scheinkomponenten sind so wie sie sind nützlich, ohne Mitgliedschaft in einem Scheinmodul, das überhaupt keine Rolle in der Testumgebung einer Spezifikation spielt.

Sicher, die Problemumgehung ist trivial ... aber diesen Fehler nur über die Google-Suche zu finden, den Thread zu lesen und zu verdauen und hilfreiche Problemumgehungen waren es nicht.

Ich füge dies einfach am Ende der Hilfsdatei hinzu, die (unter anderem) die Scheinkomponenten enthält:

/*
  mock components
  !! Each mock component added to this file *must* be added to the "MockTestModule", see below !!
*/
@Component({
  selector: 'app-mock-component',
  template: '<span>mock widget</span>'
})
export class MockComponent {}

/*
  This is an unused module to resolve the ng build error:
    'ERROR in : Cannot determine the module for class MockComponent
    in C:/code/myRepo/src/assets/test/test-resources.ts!
    Add MockComponent to the NgModule to fix it.'

  Reference: https://github.com/angular/issues/13590

  Each mock component added to this file *must* be added to the "MockTestModule"
*/
@NgModule({
  declarations: [ MockComponent ],
})
export class MockTestModule {}

Beachten Sie, dass die obige Datei in Wirklichkeit ziemlich groß ist ... das "MockTestModule" ist ganz unten am Ende der Hilfsdatei vergraben ...

... Ich hoffe, wir müssen keinen package.json-Eintrag für "ng build" schreiben, der den Aufruf abfängt und eine Konsolennachricht einfügt: "Hey UI-Einheitentester, haben Sie Ihre Mock-Komponente zum Mock-Modul hinzugefügt?" Schubs.

Hier ist, was das Problem für mich gelöst hat. Meine Struktur ist wie folgt:

├── icons.module.ts
├── index.ts
├── icon
│   ├── icon.component.html
│   ├── icon.component.ts
│   └── icon.module.ts
└── icon-indicator
    ├── icon-indicator.component.html
    ├── icon-indicator.component.ts
    └── icon-indicator.module.ts

In icons.module.ts hatte ich:

import { IconComponent } from './icon/icon.component';
import { IconIndicatorComponent } from './icon-indicator/icon-indicator.component';

export { IconIndicatorComponent, IconComponent };

@NgModule({
  /* this was all fine */ 
})
export class IconsModule {}

Die index.ts hatten:

export * from './icons.module';

Ich gehe davon aus, dass das Problem darin bestand, dass der Compiler die Module icon und icon-indicator nicht analysiert hatte, bevor er auf die entsprechenden Komponenten stieß, und daher den Fehler Cannot determine the module for class auslöste. Dieses Projekt ist ng 5. Ich habe den Fehler nur erhalten, wenn ich es in einem ng 7-Projekt konsumiere.

Die Lösung besteht darin, die Exporte eine Ebene nach unten zu verschieben. Also habe ich die Export-Anweisung in icons.module.ts entfernt und sie verschoben nach:

icon.module.ts:
export { IconComponent };
...

icon-indicator.module.ts:
export { IconIndicatorComponent };
...

und angepasst index.ts :

export * from './icons.module';
export * from './icon/icon.module';
export * from './icon-indicator/icon-indicator.module';

Hoffe, das hilft jemandem.

Ich denke, der neue Ivy-Renderer wird einige Probleme mit AOT lösen. Wie Sie den Pull-Requests und Issues entnehmen können, konzentriert sich das Angle-Team auf Ivy, sodass es keinen Sinn macht, etwas gegen dieses Problem auf Angle 6 zu unternehmen.

Ich denke, der neue Ivy-Renderer wird einige Probleme mit AOT lösen.

Das höre ich gerne bei jedem Thema.

Ich habe dieses Problem auch mit Angular 7.2.0 und Angular-Cli 7.3.0

ERROR in : Cannot determine the module for class ModalMockComponent in /Users/user/repos/angular-skeleton/src/app/shared/modal/modal.component.mock.ts! Add ModalMockComponent to the NgModule to fix it.
Cannot determine the module for class TranslatePipeMock in /Users/user/repos/angular-skeleton/src/app/shared/pipes/translate.pipe.mock.ts! Add TranslatePipeMock to the NgModule to fix it.

ZB habe ich ein TranslatePipe und ein TranslatePipeMock in meinem Shared Module . TranslatePipe ist im Modul enthalten, die Mock-Pipe nicht.
translate.pipe.mock.ts ist für Unit-Testzwecke, also kann ich diese Datei einfach in jeden Unit-Test importieren.

Aber jetzt schlägt mein Build fehl
ng build --prod

Wie beheben wir das?

Atm Ich habe eine Problemumgehung, die es löst

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "types": []
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts",
    "**/*.mock.ts"
  ]
}

Es ist schwierig, den aktuellen Status dieses Problems anhand eines kurzen Spaziergangs durch die Kommentare zu bestimmen. Ich stimme zu, dass dies ein Problem ist (schlechtes Design). Was ist der Plan, um es zu beheben? Ist es einfach oder schwierig?

@rrmayer Der Status dieses Problems ist höchstwahrscheinlich nur "Warten auf Efeu", wie bei fast allen "aktuellen" Problemen.

Wir möchten nur, dass dies von "Fehler" auf "Warnung" geändert wird, damit unsere Projekte tatsächlich kompiliert werden ... Ist das so schwer?

@Terrafire123 ... es könnte zum Beispiel viele Beziehungen zu Test- oder Build-Tooling geben, die tatsächlich darauf beruhen, dass dieser Fall zu dem Fehler führt, sodass die Änderung der Warnung ein ernsthaftes Problem darstellen könnte.

Ich habe keine Hoffnung, dass es für den aktuellen Compiler behoben wird: D

Vielleicht sollten wir zumindest die Möglichkeit haben, entweder einen Fehler oder eine Warnung anzuzeigen. Das Abbrechen von Builds, weil Komponenten absichtlich nicht Teil eines Moduls sind, ist ziemlich ärgerlich.

Ungenutzte Importe können diesen Fehler verursachen.

import { UnusedImportComponent } from "./used-somewhere-else-or-not.component";

Anscheinend bestimmt das Schlüsselwort 'export' neben der Klasse in irgendeiner Weise, dass die Klasse, auf die der @Component- Dekorator angewendet wird, in einem Modul enthalten sein muss. Ob Sie die Klasse der Komponente importieren und direkt in Tests deklarieren oder zB in CoreMocksModule deklarieren und dann das Modul importieren, spielt keine Rolle.

Es gibt jedoch eine Problemumgehung! Nehmen wir an, wir haben unsere Stub-Komponente wie folgt deklariert:

@Component({
  selector: 'app-user-stub-component',
  template: ''
})
export class UserStubComponent {}

Wir müssen das Schlüsselwort „export“ entfernen, aber irgendwie müssen wir die Komponente trotzdem exportieren, um sie im Test/Test-Modul zu verwenden. Mach es so:

@Component({
  selector: 'app-user-stub-component',
  template: ''
})
class UserStubComponent {}

export default UserStubComponent;

Jetzt müssen wir beim Importieren des Stubs überall Klammern wie folgt vermeiden:
import UserStubComponent from 'path'

Hoffe, es funktioniert. Für mich löst es AOT-Kompilierungsprobleme.

In meinem Fall habe ich es behoben. Problem war mit Gehäuse. Ich habe Großbuchstaben für Ordner verwendet, aber der automatische Import von VS-Code importierte den Pfad in Kleinbuchstaben.

@renilbabu03 JS unterscheidet zwischen Groß- und Kleinschreibung.

In meinem Fall habe ich es für meine Unit-Tests repariert, wo ich die Translate-Pipe verspottet habe.

Ich habe export class in default export geändert:

import { PipeTransform, Pipe } from '@angular/core';

@Pipe({
  name: 'translate'
})
class TranslatePipeMock implements PipeTransform { // <-- NOT: "export class TranslatePipeMock implements PipeTransform"
  public name = 'translate';

  public transform(query: string): any {
    return query;
  }
}

export default TranslatePipeMock;

Irgendwelche Fixes dafür?
Ich habe export default <class> ausprobiert, aber wenn ich ng serve --aot ausführe, wird ein Fehler ausgegeben: Unexpected value 'null' exported by the module .

Es ist sehr frustrierend.

@redplane Warum willst du das tun? Ich meine den default Export.

Warum kümmert es Angular, ob die Datei existiert, es sei denn, ich import ein exported Asset?

Meistens überarbeite ich eine Komponente oder entferne Komponenten und möchte nur die veralteten Komponentenreferenzen auskommentieren, wie ich es in den CommonJS-Tagen getan habe. Dies wäre ausreichend sicher, da ich niemals Barrel-Dateien verwende, weil ich an dieser Front zu oft verbrannt wurde, und Angular mich dazu zwingen muss, die Assets physisch aus meinem Projekt zu entfernen, ist einfach inakzeptabel, wenn ich tief im Hals bin eine Prototyping-Phase ...

Ich stecke in Angular 6 fest, weil ich der einzige Entwickler bin, der an diesem Projekt arbeitet, und es wäre die Hölle, Dinge umzugestalten, um auf die neuesten stabilen Tools zu kommen, während neue Funktionen ausgeliefert werden müssen ... also ganz am Anfang Zumindest wäre es großartig, wenn Angular 6+ mit einem Compiler-Flag gepatcht werden könnte, um dieses Verhalten zu deaktivieren ...

In meinem Fall habe ich ein eckiges Bibliotheksprojekt eingerichtet. In einer meiner Komponenten innerhalb der Bibliothek habe ich einige Aufzählungen deklariert, um diese Aufzählungen in meinem Anwendungsprojekt zu verwenden, das ich mit einem relativen Pfad zum Projektverzeichnis in meinem Anwendungsstamm importiert habe.

Aus diesem Grund wollte der Winkel-Compiler, dass meine Bibliothekskomponente in einem der ngModule des Anwendungsprojekts deklariert wird.

Um diesen Fehler zu beheben, muss ich meine Enums in der Datei public-api.ts deklarieren und sie im Anwendungsprojekt mit einem direkten Import aus der Bibliothek und nicht mit einem relativen Importpfad verwenden.

Zum Beispiel:
Name des Bibliotheksprojekts: components-lib
Name des Anwendungsprojekts: demo-app

Um Schnittstellen, Klassen, Aufzählungen usw. zu verwenden, die im Bibliotheksprojekt deklariert sind, importieren Sie sie mit einem direkten Pfad:

importiere { SearchEnum } aus 'components-lib';

und nicht tun
import { SearchEnum } from '../../../projects/components-lib/path-to-your-component';

Ich hoffe, dies hilft jemandem in der Zukunft, da ich Stunden damit verbracht habe, dies selbst zu finden.

Ich habe ein Problem mit der Aufrechterhaltung der Kompatibilität für eine Bibliothek, die mit ng 9 erstellt wurde und von der ich wollte, dass Leute, die ng 8 ausführen, diese verwenden können.

Ich biete über die Bibliothek einige Hilfsklassen an, die Ihre Komponenten erweitern können. In dieser Kette von übergeordneten Klassen sind einige davon abstrakt und müssen mit ng 9 ein @Directive({ selector: 'random' }) haben, um mit ng 8 kompatibel zu sein.

Damit wäre ich fast durchgekommen... ABER:

Cannot determine the module for class NgxSubFormComponent in /........./node_modules/ngx-sub-form/ngx-sub-form.d.ts! Add NgxSubFormComponent to the NgModule to fix it.`

Ich stelle kein Modul in der Bibliothek zur Verfügung, die Leute sollen nur die von uns angebotenen Klassen erweitern. Aber ich möchte nicht, dass sie die übergeordneten Klassen in ihre Module importieren müssen (würde keinen Sinn machen).

Ich stecke also fest und schneide einfach eine Breaking-Change-Version heraus, bei der die Leute ein Upgrade auf ng 9 durchführen müssen, anstatt Abwärtskompatibilität zu haben

Hallo zusammen, Entschuldigung für die Stille zu diesem Thema.

ngc in View Engine generiert standardmäßig ngfactory -Dateien für jede Komponente in der „Kompilierung“ – das heißt, den vollständigen Satz von TS-Dateien, die von Ihrer tsconfig definiert werden. So funktioniert TypeScript
selbst funktioniert - es kompiliert alle Dateien, die von einer tsconfig definiert werden. ngc führt darüber hinaus nur eine zusätzliche Verarbeitung durch.

Wenn also ein @Component in dieser Kompilierung vorhanden ist und ngc es sehen kann (was bedeutet, dass es sich auf der obersten Ebene befindet und exportiert wird), versucht ngc, es zu kompilieren. Es gibt keinen anderen Weg, als sicherzustellen, dass ngc die Datei, die die Komponente überhaupt deklariert, nicht kompiliert.

Der richtige Weg, dies zu tun, besteht darin, Ihre tsconfig zu erweitern. Beispielsweise könnten Sie eine tsconfig der obersten Ebene für Ihren Editor haben, die alle Dateien enthält, und dann eine tsconfig.app.json speziell für Ihre Anwendungskompilierung, die von der Editorkonfiguration erbt und Spezifikationsdateien ausschließt. Nur die App-Konfiguration würde mit ngc kompiliert werden.

Projekte (jedes tsconfig ist ein "Projekt") sollten so strukturiert sein, dass eine Komponente und ihr Modul immer zusammen kompiliert werden.

In Ivy gelten immer noch weitgehend die gleichen Regeln, mit einigen kleinen Unterschieden:

  • Standardmäßig versucht Ivy, _any_ @Component zu kompilieren, unabhängig davon, ob es exportiert wird.
  • In Ivy ist es kein Fehler mehr, eine Komponente ohne Modul zu haben. Sie erhalten jedoch weiterhin Fehler bei der Überprüfung des Vorlagentyps, wenn diese Komponente versucht, andere Komponenten/Direktiven in ihrer Vorlage zu verwenden, da ohne ein Modul für diese Komponente nichts anderes sichtbar ist.
  • Es ist möglich, den Ivy-Compiler anzuweisen, eine bestimmte Komponente oder ein bestimmtes Modul zu ignorieren und es bis zur Laufzeit zu belassen, indem dem Decorator ein jit: true -Flag hinzugefügt wird.

@alxhub Ich bin froh zu hören, dass es kein Fehler mehr ist!

Ich verstehe, dass ngc versuchen wird, alles zu kompilieren, was tsc tun würde, und dass tsc alles in seinem Bereich kompilieren wird. Abgesehen davon ist die Anforderung, dass eine Komponente zu einem Modul hinzugefügt werden muss, zu 100 % ein eckiges Anliegen, sodass es sich anfühlt, als würde man die Dose die Straße runter treten, wenn man sie aus dem Umfang Ihres Typoskript-Projekts entfernt. Da Muster wie Barrel-Dateien üblich sind, kann es außerdem schwierig sein, eine einzelne Datei wirklich aus der Kompilierung zu entfernen, ohne sie dabei AUCH aus allen erneuten Exporten zu entfernen. Aus diesem Grund stießen die obigen Aufrufe, einfach „diese Komponenten auszuschließen“, oft auf Unzufriedenheit.

In Bezug auf die verbleibende Einschränkung bei Ivy (die Vorlagenfehler bei Komponenten ohne Module), ist es zu viel verlangt, dass diese auch Warnungen sind? Ich verstehe, dass dies schwieriger (oder unmöglich) sein kann, wenn die Typprüfung erfolgt, bevor die Komponente als modullos identifiziert wird, aber es scheint mir, als würde eine Warnung im Sinne von Warning: ExampleUnusedComponent does not belong to an NgModule, and will be excluded from the output die Idee genau erfassen, dass die Komponente (und alle anderen, auf die von ihr verwiesen wird) werden nicht eingeschlossen, es sei denn, sie werden einem ngModule hinzugefügt.

Insgesamt freue ich mich sehr über die Bewegung in dieser Angelegenheit und freue mich darauf, meinen ursprünglichen Anwendungsfall mit den neuen Änderungen im Ivy-Compiler auszuprobieren!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen