Angular: Compilation Angular2 AOT - "Impossible de déterminer le module pour la classe (... de nombreux composants inutilisés)"

Créé le 20 déc. 2016  ·  183Commentaires  ·  Source: 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

Comportement actuel
Les composants/tubes/directives inutilisés dans mon espace de travail sont détectés par le compilateur, qui génère l'erreur Cannot determine the module for class (...) pour chaque fichier. Il arrête la compilation, et ne semble pas configurable. C'est un problème, car j'ai besoin d'avoir ces fichiers dans mon espace de travail, mais je n'en ai pas besoin dans l'application résultante (implémentations partenaires nécessitant différentes combinaisons de composants partagés). Ceci est particulièrement frustrant en ce qui concerne la compilation dans un chargeur Webpack, qui devrait pouvoir fournir une liste des fichiers inclus, quel que soit l'espace de travail.

Comportement prévisible
Je m'attendrais à ce que ces erreurs soient des avertissements et/ou puissent être réduites au silence par une option du compilateur. Alternativement, en ce qui concerne le webpack, vous pouvez autoriser l'insertion d'une liste de fichiers, de sorte qu'un webpack puisse fournir tous les fichiers de la chaîne requise, au lieu de tous les fichiers de l'espace de travail.

Reproduction minimale du problème avec instructions
Impossible de faire une démonstration dans plunkr, car il utilise JIT.

  1. Créez une application angulaire de base qui démarre un ngModule avec un composant, AppComponent
  2. Mettez cette application dans un état qui peut être compilé AOT (cela devrait être assez facile avec un monde hello)
  3. Ajoutez un composant à la structure du répertoire, mais ne le référencez nulle part dans votre code.
  4. Essayez à nouveau de compiler AOT. Vous recevrez l'avertissement Cannot determine the module for class

Quelle est la motivation / le cas d'utilisation pour changer le comportement ?
Mon entreprise a une application de base pour elle-même et nos partenaires utilisent des versions modifiées de cette application comme étant les leurs. Plutôt que de gérer tous les partenaires séparément, nous utilisons une bibliothèque partagée de composants génériques communs, importés selon les besoins. Pour notre application de base, tout va bien, puisque nous utilisons tous les composants. Pour les partenaires, nous ne pouvons pas utiliser AOT, car certains des composants du package npm partagé n'ont pas de module déclaré.

Veuillez nous parler de votre environnement :
Cela se produit sur tous les appareils, mais la configuration de test actuelle est :
Windows 10
Code VS
Commande (terminal bash)

  • Version angulaire :
    v2.1.0 (bien que nous ayons également testé en 2.3.1

  • Navigateur : Tous - il s'agit d'un problème de compilateur, pas spécifique au navigateur

  • Langue : Tapuscrit

  • Nœud (pour les problèmes d'AoT) : nœud v6.3.0
P5 compiler NgModule ve low error messages triage #1 confusing

Commentaire le plus utile

@DzmitryShylovich Il est logique que les composants que vous UTILISEZ doivent faire partie d'un module. Mais en ce qui concerne le compilateur, ces fichiers ne devraient pas avoir d'importance. Ce sont des fichiers .ts inutilisés et non référencés qui contiennent des composants.

Tous les 183 commentaires

Impossible de déterminer le module pour la classe

Le composant doit faire partie d'un module. C'est voulu.
Je dirais que c'est une demande de fonctionnalité.

@DzmitryShylovich Il est logique que les composants que vous UTILISEZ doivent faire partie d'un module. Mais en ce qui concerne le compilateur, ces fichiers ne devraient pas avoir d'importance. Ce sont des fichiers .ts inutilisés et non référencés qui contiennent des composants.

@swimmadude66 vous pouvez exclure les fichiers inutilisés dans tsconfig

@DzmitryShylovich vous pouvez, mais les fichiers baril compliquent cela. Si une classe est réexportée dans un fichier baril, je dois également ignorer le fichier baril, ce qui peut causer des problèmes avec les classes dont j'ai besoin à partir de ce baril.

Il semble étrange que le compilateur essaie de compiler plus qu'il ne le doit absolument. Tree-shaking mis à part, je m'attendrais à ce que le compilateur ne veuille traiter que les fichiers qui lui sont donnés ou explicitement liés à des fichiers donnés.

Il semble étrange que le compilateur essaie de compiler plus qu'il ne le doit absolument.

c'est ainsi que fonctionnent les compilateurs...

Le fait que la compilation JIT fonctionne devrait être une assez bonne preuve que le compilateur n'a pas BESOIN de ces fichiers. Il lance une erreur au lieu d'un avertissement sur les fichiers qui pourraient être exclus sans aucun dommage.

vous pouvez me parler du fonctionnement des compilateurs toute la journée, mais c'est un vrai problème dans un cas d'utilisation quelque peu basique. Je demande seulement un moyen de supprimer au moins l'erreur et de continuer à mes risques et périls.

Mon collègue tente de supprimer tous les fichiers baril qui pourraient nous empêcher d'utiliser les exclusions globales, mais je vous demanderais de jeter un œil au problème que j'ai initialement ouvert contre @ngtools/webpack, où un autre utilisateur a eu la même erreur de un composant uniquement référencé dans leurs tests. https://github.com/angular/angular-cli/issues/3636

Le compilateur est conscient des fichiers que je ne lui demande pas de compiler, et il génère des erreurs irrécupérables pour les situations récupérables. clair que ça.

Je ne comprends pas pourquoi vous avez des composants dans le même répertoire qui ne sont pas inclus dans le projet.
Je pense que cela pourrait être une demande de fonctionnalité, mais actuellement, c'est ainsi que fonctionne le compilateur, dire également "cela fonctionne dans JIT" n'est pas une raison suffisante pour penser que cela devrait fonctionner dans AOT.
Ce que je pense que vous devez faire est de séparer ces fichiers de votre application de base en modules, puis de les importer via une sorte de gestionnaire de packages, de cette façon, cela résout vos problèmes, range votre répertoire et facilite la maintenance de tous les aspects

@Toxicable les fichiers inutilisés se trouvent dans un module npm de style bibliothèque. Généralement, le cas d'utilisation idéal ressemble à ceci :

dans @project/angular (notre module npm de code partagé), nous avons tous les composants, canaux, directives et services nécessaires pour créer notre application de base et communiquer avec notre plate-forme backend. Nos partenaires veulent une application qui ressemble, mais qui utilise une page d'accueil différente ou qui a un nouveau composant ajouté. Cependant, la plupart des autres pages seront les mêmes, et tous les services nécessaires pour se connecter à notre plateforme pourraient être les mêmes.

Notre approche pour maximiser le code réutilisable consistait à demander à chaque partenaire de créer des modules et d'importer une combinaison de nouveaux éléments et d'éléments partagés à partir du module npm. Mon nouveau HomeModule pourrait avoir une importation comme :

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

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

cela explose alors dans AOT en disant: Cannot determine the module for class OverviewComponent puisque nous n'utilisons pas le OverviewComponent de @project/angular.

Puisque littéralement aucun fichier ne pointe vers @project/angular/components/home/overview/component.ts , je ne m'attendrais pas à ce que le compilateur se soucie du tout qu'il soit inutilisé. mais comme le fichier existe dans le répertoire node_modules de notre projet, le compilateur le trouve, se plaint et meurt.

En ce qui concerne le JIT fonctionne !== AOT fonctionne, l'application de base fonctionne avec AOT, et les changements dans le partenaire Proof of Concept sont incroyablement petits. Je ne veux pas dire que tout ce qui fonctionne dans JIT devrait fonctionner dans AOT, mais j'ai de très bonnes raisons de croire que cela devrait.

J'ai un autre exemple où ce comportement actuel n'a pas de sens - les tests.
Disons que j'ai un répertoire de fonctionnalités some-feature , avec some-feature.component.ts et some-feature.component.spec.ts .
Ce composant utilise la projection de contenu, donc je voudrais tester cette fonctionnalité en créant un composant de test dans mon fichier some-feature.component.spec.ts qui utilise le composant some-feature dans la vue, comme ceci :

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

J'utilise ensuite ce composant dans mon module de test :

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

Tout est valide et génial, jusqu'à ce que j'exécute ng build --prod --aot en utilisant angular-cli, qui lance :
Cannot determine the module for class TestAppComponent .

Je ne pense pas qu'AOT devrait être concerné par les fichiers .spec ..

La règle générale est la suivante : ngc compilera tout ce que tsc compilera. Et il essaiera de compiler chaque composant qu'il trouve. Cependant, Angular ne peut pas compiler des composants sans module associé.

Nous pourrions cependant transformer cette erreur en avertissement.

J'ai également des composants d'emballage de test qui sont utilisés uniquement pour les tests et qui font exploser AOT comme décrit ici. Ce serait bien si AOT pouvait ignorer tous les composants qui satisfont une expression générique comme TestComponent * etc.

D'accord, donc plus d'infos ici. Nous semblons avoir trouvé une solution de contournement pour notre cas (ne corrige pas le cas testWrapper). Il semble que le vrai problème dans notre cas était nos fichiers barils. Lors de l'importation de N'IMPORTE QUOI à partir d'un fichier baril, il suit la chaîne de toutes les choses réémises par les barils. Étant donné que nous utilisions nos composants à partir d'un niveau supérieur PROJECT/components , il analysait TOUS les composants au lieu de celui que nous voulions. Ce serait probablement encore mieux comme avertissement, mais je peux comprendre un peu mieux pourquoi le compilateur s'est soucié de ces composants.

voir la même erreur:

$ ./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

Évier de cuisine angulaire 2 : http://ng2.javascriptninja.io
et source@ https://github.com/born2net/Angular-kitchen-sink
Salutations,

Sean

i18 ne doit pas parcourir toute la structure du projet et plutôt regarder les déclarations utilisées.

J'ai essayé de nettoyer les directives qui ne sont pas utilisées, et le terrier du lapin est devenu plus profond :

$ ./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'.

permettez-moi d'ajouter que tout fonctionne bien avec angular-cli et angular-compiler, donc c'est juste i18 qui n'aime pas mon projet.

Référence (configuration agréable et propre): https://github.com/born2net/ng-skeleton

Salutations,

Sean

Même erreur pour les composants commentés .. les composants inutilisés et commentés pour l'étape de développement ne sont qu'une étape utile à ne pas traiter

// two comments aot read:

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

@kirjai ngc compile tous les fichiers dans un répertoire source. peu importe si vous l'importez ou non.

@DzmitryShylovich que je comprends, je dis simplement que je ne pense pas que l'AOT devrait se soucier de ce fichier dans ce cas .. dans mon esprit, ignorer les fichiers .spec lors de la compilation AOT est la voie à suivre. Mais il y a clairement quelque chose qui empêche l'équipe de faire ça, je comprends.

Comme alternative, alors peut-être que le fait de placer les fichiers .spec dans le même répertoire que l'entité pour laquelle les tests sont écrits ne devrait pas être suggéré par le guide de style ?

Je rencontre également ce message d'erreur (et quelques autres) à cause de notre code de test et de l'AOT en combinaison.

Je peux recommander cet article . Il explique comment certains messages d'erreur peuvent être provoqués et comment les corriger/contourner.

Considérant que les gens tomberont sur ce problème précis s'ils suivent le guide de test officiel et créent leur application avec AOT, vous voudrez peut-être mettre à jour le guide ?

(Si quelqu'un cherche une réponse concernant RouterLinkStubDirective )
_Vous pouvez y remédier en ajoutant un module "factice":_

/**
 * 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 {
}

Au fait, il essaie également de déterminer le module pour les classes abstraites :
export abstract class AsyncTransform extends AsyncPipe implements PipeTransform { ... }

"Erreur : Impossible de déterminer le module pour la classe AsyncTransform"

L'ajouter à un module ne fonctionne pas non plus 😄.
"Impossible d'affecter un type de constructeur abstrait à un type de constructeur non abstrait."

cela se produit également pour certaines classes.

Err : Impossible de déterminer le module pour la classe AppGlobalModalComponent

export class CustomGlobalModalComponent extends AppGlobalModalComponent {}

@gestj comme l'a souligné @Phmager , les modules factices ne sont pas une solution pour tous les cas. De plus, ils constituent une solution assez saugrenue, car vous finissez par compiler du code dont vous ne voulez pas ou dont vous n'avez pas besoin.

Pour notre cas, nous avons corrigé le problème d'une manière différente. Nous avons déplacé nos composants partagés vers une bibliothèque npm et ignoré node_modules dans notre tsConfig. J'ai mentionné plus haut que cela ne fonctionne toujours pas, mais uniquement parce que nous utilisions des fichiers baril. Si vous pointez directement sur chaque classe dont vous avez besoin dans node_modules, il ignorera les autres. Cependant, dès que vous pointez sur un baril, il génère l'erreur pour les fichiers inutilisés dans le même baril.

Ce n'est pas idéal, car cela tue toutes nos merveilleuses limes à canon, mais au moins c'est prévisible.

En espérant toujours que cette erreur soit rétrogradée en avertissement

Excellent travail effectué dans l'équipe Angular jusqu'à présent.
Nous utilisons beaucoup Angular dans nos projets et après un an à essayer de comprendre toutes ces choses bourdonnantes d'Angular2+, voici ma conclusion :
1- Angular est massif et lent, vous voulez le rendre rapide ? utilisez AOT et LazyLoading et gzippez vos trucs.
2- Vous voulez lazyLoad un composant ? NON, vous seriez en mesure de charger un itinéraire paresseux, donc si votre application est massive mais qu'une seule page, profitez d'une taille de paquet de 8 mg.
3- Vous voulez utiliser AOT ?? AOT est bogué et difficile à respecter et à ne pas utiliser des tas de fonctionnalités javascript/es6 et probablement à réécrire beaucoup de votre code.
4- Vous utilisez bien AOT ? Très bien, jetez maintenant un œil à votre bundle final, il est maintenant encore plus gros que @angular/compiler plus vos composants non AOTed, bravo.

5-Dans le cadre des avantages d'Angular2+, vous pouvez désormais utiliser gzip, juste au cas où vous ne sauriez pas l'utiliser auparavant, maintenant qu'Angular est massif, vous l'apprendrez mieux :) Alors voilà, ils vendons gziping comme une option pour optimiser le code Angular2 :)

@ xe4me Veuillez garder la discussion dans ce fil pertinente pour le problème en question, plutôt qu'une simple diatribe générale contre le cadre.

build:dev dans https://github.com/AngularClass/angular2-webpack-starter convertit automatiquement une chaîne en un tableau de chaînes pour correspondre à une définition de fonction, build:aot affiche l'erreur. Au cours du développement, il semble que des builds AOT fréquents soient nécessaires.

J'ai le même problème et j'ai trouvé une solution, peut-être que cela fonctionne aussi pour vous.

Mon scénario était le suivant :

J'ai un MapPipes.ts, contenant deux Pipes.

L'un des Pipes a été utilisé dans mon module, l'autre non. Ainsi, je n'ai pas enregistré le second dans la partie "declaration:" de mon décorateur @NgModule . Le problème est arrivé à cette seconde.

J'ai également enregistré ceci (bien qu'il n'ait pas été utilisé), et maintenant cela fonctionne.

Ma suggestion est de changer le compilateur angulaire de manière à ce qu'il essaie de trouver des modules uniquement pour les entités angulaires réellement utilisées.

J'ai eu cette erreur avec une classe abstraite qui extends NgClass . La suppression de l'héritage semble résoudre ce problème, mais crée évidemment d'autres problèmes.

@DzmitryShylovich @kirjai ce n'est qu'un problème avec TestComponents dans un fichier de spécification si vous les exportez. Et comme ils ne doivent généralement être utilisés que dans le même fichier, il n'est pas nécessaire de les exporter. Problème résolu pour moi.

Honnêtement, c'est ridicule, je n'ai vraiment rien d'autre à dire à ce sujet à part le fait que je suis de nombreuses heures et pourtant toujours incapable d'obtenir quelque chose qui fonctionne sous JIT en travaillant avec AOT (je devrais être clair, ce n'est qu'un des environ une demi-douzaine de numéros à ce jour).

@cwmrowe c'est bien, mais que se passe-t-il si vous en avez un qui est réutilisé dans plusieurs fichiers de spécifications ? Cela semble cassé pour être honnête.

Dans mon cas, je travaillais sur 2 projets différents dans la même application principale Angular 2. J'ai 2 dossiers nommés d'après nos clients, disons some-domain.com et some-other-domain.com . L'application est exactement la même pour les 2 projets et ne diffère que par un peu de style et quelques composants personnalisés mineurs. Aujourd'hui, j'ai besoin de compiler l'application pour le client A, et plus tard, je veux compiler pour le client B. Dans le code, c'est aussi simple que de changer 1 ligne de code pour moi :

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

Je décommente simplement le domaine que je veux aussi compiler et cela fonctionne.

Nous avons le même problème avec l'héritage et les classes abstraites et nous n'avons trouvé aucune solution. Nous avons des composants qui étendent un composant abstrait. Dans JIT, tout fonctionne très bien, mais dans AOT, les modules pour les composants abstraits sont introuvables et il n'est pas possible de déclarer des composants abstraits dans un module.

Actuellement, nous n'avons pas d'autre solution que d'éviter les modèles de conception oop et d'utiliser du code redondant.

@jabaa supprimer l'annotation @Component de votre classe abstraite

@DzmitryShylovich Lorsque je supprime @Component , le constructeur n'est pas hérité. Je dois injecter tous les injectables dans tous les composants au lieu du composant abstrait. C'est du code redondant. Lorsque je change le constructeur et les services de la classe abstraite, je dois adapter tous les composants enfants.

Actuellement, nous contournons ce problème en implémentant toutes les méthodes abstraites avec des méthodes factices et en créant un module factice pour tous les composants abstraits. Mais alors quelqu'un pourrait oublier de remplacer la méthode factice. C'est juste un travail autour.

@jabaa quelle version utilisez-vous ? constructeur doit être hérité indépendamment de @Component .

@bigjetplane Je ne sais pas où se situe le problème, mais lorsque je supprime @Component , j'obtiens une erreur indiquant que les dépendances du composant sont introuvables. Autant que je sache, DI ne fonctionne que pour les classes avec des décorateurs angulaires. Ainsi, lorsque je supprime les décorateurs, les dépendances ne sont pas injectées. Nous utilisons Angular 4.

@jabaa est-il rompu avec jit ou aot, ou les deux ?

@bigjetplane Voici le plongeur avec le problème. Il y a une classe abstraite avec décorateur et tout fonctionne en jit. Lorsque vous supprimez le décorateur de la classe abstraite, l'application ne peut pas s'afficher car toutes les dépendances n'ont pas pu être chargées : Can't resolve all parameters for App: (?).

C'est notre cas d'utilisation. Nous avons une classe abstraite avec un constructeur et des injections. Nous voulons uniquement remplacer certaines méthodes abstraites dans les composants enfants

L'exemple donné ne fonctionne pas dans aot. La différence entre aot et jit est un gros problème pour nous. Nous développons avec jit. La version de production est avec aot. Nous développons donc une semaine avec jit sans erreurs ni avertissements et après la semaine, nous voulons une version de production et obtenons de nombreuses erreurs de nulle part. Je préfère un commutateur pour jit, où je peux activer les erreurs aot. Une construction jit nécessite 10 à 20 secondes. Une construction aot nécessite 25 minutes.

@tbosch Un mot sur le changement de ceci en avertissement ? Il semble que depuis ma dernière visite, plusieurs autres personnes ont ajouté leurs propres anecdotes, et je me demandais si vous pouviez nous donner une mise à jour.

Merci!

J'ai aussi le même problème.

Dans mon cas, je travaillais sur 2 projets différents mais en incluant les composants communs via un projet de bibliothèque angulaire interne ajouté en tant que dépendance dans package.json.

Comme il s'agit d'un projet de bibliothèque, les composants inutilisés du référentiel de composants génèrent l'erreur ci-dessous lors de la compilation d'une version de prod AOT.

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!

On dirait que je dois créer un module pour chaque composant et utiliser :(

Toute solution à ce problème aidera beaucoup.

J'espère aussi une solution à ce problème. Apparemment, l'utilisation de composants stub pour les tests est prévue par les développeurs Angular - il doit donc également être possible de les exclure de la construction de manière propre. Pour l'instant, j'utilise la solution de contournement suggérée par gestj (définir un faux module dans lequel le composant stub est déclaré).

Ainsi, lorsque vous utilisez des composants stub pour les tests, vous souhaitez nommer votre composant avec le suffixe spec.ts comme whatever.component.spec.ts . De cette façon, tsc ignorera ces fichiers (étant donné qu'ils sont exclus de votre tsconfig) et sera donc également ignoré par ngc.

EDIT : il s'avère qu'il s'agit d'une erreur différente, résultant d'un bogue dans ngtools/webpack. Ce ticket a été ouvert ici : https://github.com/angular/angular-cli/issues/6228


Nouveau plaisir sur ce front pour mon entreprise. Lors d'une récente tentative de mise à niveau de nos systèmes vers la v2.4.10, je me suis retrouvé avec quelques dizaines d'erreurs de cette variété :

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

Il semble se connecter pour tous les composants de notre bibliothèque partagée qui ne sont pas utilisés par l'application actuelle. Ceci est étrangement similaire à l'erreur pour laquelle j'ai ouvert le ticket à l'origine.

Je ne sais pas ce que nous pouvons faire d'autre à ce sujet cependant. Nous avons essayé d'adresser directement chaque composant dont nous avons besoin à partir de la bibliothèque partagée (sans utiliser de fichiers index.ts , car ceux-ci semblaient extraire tous les fichiers référencés dans l'index) et de déplacer toutes les bibliothèques partagées vers node_modules.

Pourquoi le compilateur doit-il connaître chaque composant angulaire de mon dossier node_modules ? Même s'il a besoin de les lire pour construire sa carte, il ne devrait pas se soucier de savoir s'ils ont ou non un module !

@ swimadude66 , oui, nous avons rencontré ce problème en travaillant avec notre bibliothèque https://github.com/WealthBar/a2d3 . Même si elle ne fournit aucun composant basé sur un modèle (juste des directives), la bibliothèque doit toujours être construite avec le compilateur AoT ou elle ne fonctionnera pas avec les versions AoT lorsqu'elle est utilisée.

@chrisnicola Vous dites que la bibliothèque doit être pré-compilée avec AoT avant d'être publiée ? car cela impliquerait que la bibliothèque possède ses propres modules, ce qui semble vraiment contre-intuitif. En l'état, la bibliothèque est constituée de fichiers ts non compilés, que nous récupérons comme n'importe quel autre fichier de notre projet. Le tout est ensuite compilé avec le plugin @ngtools/webpack vers webpack.

Il convient de noter que même l'erreur d'origine de ce ticket a été "corrigée" de notre côté jusqu'à la v2.1.1 en éliminant simplement toutes les références aux fichiers index.ts. Ce correctif ne semble plus fonctionner pour la v2.4.10.

Ah je vois, oui j'ai mal lu ton problème. Vous n'êtes pas en train d'extraire une bibliothèque partagée pré-compilée via NPM ici, vous avez une bibliothèque TS locale dans votre projet. Ai-je bien compris maintenant ?

Je suis d'accord que cela devrait "fonctionner simplement" et vous avez raison, cela ressemble définitivement au même problème où il trouve des composants qui n'ont pas de module dans l'application. Une solution possible serait d'utiliser une construction AoT spécifique tsconfig.json qui exclut les fichiers et dossiers qui ne sont pas nécessaires pour la construction AoT.

J'ai réussi à résoudre tous nos problèmes liés à cette erreur.
Le problème (et la solution) apparaît lors de l'exportation.

Nous avions un composant qui n'était utilisé que pour les tests. Il a été exporté à partir d'un autre fichier afin de pouvoir être réutilisé - cela a causé des problèmes lors de l'exécution de notre cible i18n.

Pour le résoudre, nous venons de déclarer un module (assurez-vous de l'exporter également):

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

Notre autre composant qui a causé une erreur était un composant inutilisé qui a piraté i18n.
Il était exporté afin d'être récupéré par l'outil i18n mais cela provoquait la même erreur que l'autre composant.

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

Encore une fois, en utilisant la technique IgnoreModule, nous pourrions facilement la contourner.

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

@UtopianStorm ce n'est pas une solution. Il a été mentionné ci-dessus qu'avoir un "UnusedModule" est non seulement difficile à mettre à l'échelle, mais crée également un module entier de fichiers source qui ne devrait pas être inclus dans le bundle de distribution.

@Phmager Avez-vous déjà trouvé une solution pour le problème des composants abstraits ? Je retire mes cheveux.

@ swimmadude66 Ce n'est pas une solution dans le sens où c'est définitivement une solution de contournement - mais cela surmonte l'erreur.
Je ne sais pas à quel point ce serait difficile à mettre à l'échelle car la technique peut être appliquée à chaque fois que le problème survient.

Cela encombrera votre paquet de distribution, mais cela aura-t-il de l'importance ? De l'état d'Angular, j'ai en quelque sorte supposé qu'il serait déjà jonché de nos fichiers de spécifications.
Dans tous les cas, c'est une approche beaucoup plus propre que d'atteindre directement les entrailles du dossier node_modules, n'êtes-vous pas d'accord ?

Au moins à partir du cas d'utilisation pour lequel j'ai initialement ouvert le ticket, ce n'est même pas une solution de contournement viable. Il n'est pas possible pour chaque équipe partenaire de maintenir une liste des composants partagés inutilisés au fur et à mesure.

De plus, expédier essentiellement 2 applications complètes simplement parce que le compilateur est trop strict est un compromis que je ne suis pas prêt à faire. Angular est déjà assez volumineux, et je ne peux pas justifier l'envoi d'un module entier de composants inutilisés juste pour rendre heureux leur compilateur opiniâtre.

@swimmadude66 je vois. Si vous pensez que l'ajout d'un autre module fait une si grande différence, je ferais mieux de le revoir moi-même - parce que je ne préconisais pas simplement de créer un module inutilisé à partager pour l'ensemble du projet, mais un module pour chaque composant que je devais libérer du compilateur trop strict - potentiellement dusins.

Il convient de noter que notre base de code partagée est assez volumineuse, donc un module inutilisé serait de loin le plus gros module de l'application. Notre situation n'est pas typique à 100%, mais reste dans les limites de la raison d'être soutenue, je crois.

Honnêtement, après 5 mois à regarder ce ticket aller nulle part, nous examinons d'autres options, y compris simplement tuer notre dépôt de code partagé

Je suis confronté exactement au même problème que vous, @swimmadude66 . Le fait qu'il ne s'agisse pas d'un avertissement supprimable est ridicule.

Chère équipe Angular, y a-t-il quelque chose que vous puissiez faire à ce sujet ?

@DzmitryShylovich Comment exclure un fichier mock.ts que je n'utilise pas ? J'ai essayé de le mettre dans tsconfig.app.json , tsconfig.json et tsconfig.ng-cli.json et aucun ne semblait fonctionner.

Face au même problème avec exactement le même cas d'utilisation - nous utilisons Rollup, donc les composants inutilisés n'arrivent même pas au bundle ultime.

Veuillez supprimer cela ! C'est une grande nuisance, et arrête le travail.

Je viens de tomber sur ça aussi, tellement frustrant.

@mlakmal et d'autres, qui obtiennent une erreur sur le code comme

export class CustomGlobalModalComponent extends AppGlobalModalComponent {}

Supprimez l'annotation @Component de AppGlobalModalComponent ou déclarez AppGlobalModalComponent (si elle est utilisable) dans NgModule

J'ai créé une directive fictive pour l'utiliser dans mes tests. Et obtenez ce problème avec la compilation AOT. Je ne veux pas importer cette directive fictive dans des modules simples. Veuillez corriger cela.

Je me demande si la balise "freq1: low" sur ce problème est due au fait que l'AoT est une douleur si spectaculaire dans le cul pour se mettre au travail, que les gens ne s'en soucient même pas ? Il est un peu incroyable qu'un problème aussi simple mais douloureux n'ait reçu pratiquement aucun retour de la part des principaux contributeurs d'Angular.

Quoi qu'il en soit, il existe un moyen d'exclure des fichiers qui n'ont pas été spécifiquement mentionnés. Si vous avez un modèle de nommage (par exemple .spec.ts , .abstract.ts , .stfu-aot.ts ), vous pouvez créer un fichier tsconfig.json séparé pour AoT et l'utiliser à la place : ngc -p tsconfig-aot.json . Dans ce fichier, vous pouvez utiliser le "exclude": ["./app/**/*.stfu-aot.ts"] pour exclure les fichiers. C'est ennuyeux, mais ça devrait marcher.

Edit : ce qui précède ne semble pas fonctionner avec les classes abstract qui héritent d'un composant. Yay :(

Je viens de rencontrer cela aussi, tellement frustrant. Lors de la construction, le composant commun ne peut pas être partagé dans une autre application

certains des cas courants pour ce problème, évitez d'ajouter @Component à votre classe de services :

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

J'ai un scénario où j'injecte un service dans un service. À première vue, cela semble être une chose facile à mettre en œuvre, il suffit d'ajouter @Component. La documentation angulaire doit donc être mise à jour pour afficher cette solution pour les services complexes : pour résoudre ce problème, j'ai supprimé @Component. Dans le constructeur du Service j'ai ajouté :
constructor(@Inject(ExampleService) private exampleService: ExampleService)

vous n'avez pas besoin d'ajouter un décorateur @Component() à aucun service. Seulement @Injectable()

FWIW J'ai un MockXYZComponent qui étend XYZComponent un composant d'application mais n'est utilisé que dans les spécifications (a le même sélecteur et ne peut donc pas être importé dans AppModule ).

N'est-ce pas un cas d'utilisation valide ?

@alastair-todd pas sûr de comprendre ce que tu veux dire. Si vous utilisez un composant en tant que composant, vous ajoutez un décorateur @Component() . Si vous utilisez le composant comme base - uniquement pour en hériter, mais pas en tant que composant, vous n'avez pas besoin d'utiliser le décorateur - mais simplement hériter et utiliser le décorateur sur "successeur".
À propos des tests unitaires - je ne peux pas répondre, vous devez probablement créer un TestModule spécial ? Je ne fais pas de tests unitaires pour le moment.

@tytskyi J'ai compris que l'héritage du décorateur n'était pas pris en charge. Cela a-t-il changé récemment ?

le cas d'utilisation consiste à se moquer d'un sous-composant comme ci-dessous. Les deux ont besoin de la directive @Component pour sélectionner le sélecteur.

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

Pourtant, cela génère l'erreur de compilation OP AOT.

Mon point de vue est un cas d'utilisation valide, auquel cas la compilation AOT est trop zélée et/ou ignore les spécifications dans le cadre du projet.

Peut-être que ma solution aidera quelqu'un : je viens de créer un module factice qui déclare tous les composants fictifs. Ce module n'est importé par rien - il garde juste le compilateur AoT heureux. Par conséquent, aucun des composants fictifs ne fait partie du code compilé. Pas idéal, mais problème résolu.

J'aimerais entendre parler d'une meilleure solution.

C'est tellement étrange et embarrassant que ce problème a été ouvert en décembre 2016 et a toujours ce problème. J'ai converti la structure de toute mon application pour utiliser une compilation aot. J'ai 4 modules qui sont chargés paresseux et plus de 60 composants. Le compilateur ne se plaint que de quelques composants (selon ce que suggère l'erreur) qui, j'en suis sûr, font déjà partie des déclarations de l'un des modules chargés paresseux, ce qui m'est un peu étrange.

Il donne même des erreurs sur des composants qui font déjà partie de certains modules.

Même problème

Le compilateur d'Angular regarde l'ensemble de fichiers que vous avez remis à tsconfig - donc l'exclusion de fichiers à partir de là devrait les exclure de cette vérification.

C'est vraiment embêtant :(

@alastair-todd désolé, j'ai perdu la notification de votre question dans des tonnes d'autres notifications. Vous avez raison -
L'héritage de décorateur n'est pas pris en charge.

Voir la réponse de @robwormald

Le compilateur d'Angular regarde l'ensemble de fichiers que vous avez remis à tsconfig - donc l'exclusion de fichiers à partir de là devrait les exclure de cette vérification.

Vous pouvez donc essayer de créer une convention pour les noms de fichiers fictifs, comme : selection-tool.component.mock.ts . Puis exclure via

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

accidentellement cliqué sur le mauvais bouton, désolé !

+8 mois et c'est toujours un problème. Même problème ici ERROR in Cannot determine the module for class PasoFooterComponent

Je pense qu'il est vital pour les développeurs d'Angular d'ignorer ces fichiers.

Si quelqu'un peut me donner des conseils sur l'endroit où je peux trouver ce code, je serai heureux
pour le réparer moi-même. C'est une nuisance très gênante. J'ai couru dedans
encore hier.

Si quelqu'un pense qu'il s'agit d'une fonctionnalité et non d'un bogue, que diriez-vous d'avoir un drapeau
pour ça?

Le mercredi 9 août 2017 à 02h40, Leonardo Vidal [email protected]
a écrit:

+8 mois et c'est toujours un problème. Même problème ici ERREUR dans Impossible
déterminer le module pour la classe PasoFooterComponent


Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/angular/angular/issues/13590#issuecomment-321082545 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AEM6r7FOTLcicWJN3Oijw2pwKTLGL6cFks5sWM61gaJpZM4LSAwS
.

@samirotiv Avez-vous une reproduction ?
Comme l'a dit @robwormald

Le compilateur d'Angular regarde l'ensemble de fichiers que vous avez remis à tsconfig - donc l'exclusion de fichiers à partir de là devrait les exclure de cette vérification.

J'ai eu le même problème mais j'ai réussi à le résoudre. Je viens de regarder comment ts transpile mon app par exemple

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

Et j'ai remarqué que le script dactylographié ne compilait pas mes modules chargés paresseux parce que j'utilisais l'option tsconfig "files"

Je reçois cette erreur sur la classe abstraite (sans décorateurs)

J'ai commencé à rencontrer ce même problème récemment moi-même.

+1 pour changer l'erreur en avertissement.

Cela semble être une solution facile. Pourquoi le retard ?

C'est une exigence de base - laissez les fichiers non référencés.
Cette restriction est un problème pour les grands projets. Veuillez changer ceci en avertissement.

Il y a des cas où vous publiez un package qui prend en charge différentes versions d'angular. et l'utilisateur doit choisir l'un d'entre eux.

Par exemple, un package qui fournit des fichiers pour HttpClient (Angular >= 4.3 utilisateurs) et Http (Angular < 4.3 utilisateurs)

Actuellement, ngc compile tous les fichiers d'un répertoire source, que vous les utilisiez ou non ! ou la construction échoue.

Ce que j'ai fait c'est ça :

J'ai enregistré tous mes composants stub / mock avec une extension .mock.ts et mis à jour le tableau "exclude" tsconfig.app.json comme suit :

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

AOT ignore maintenant la compilation de ces fichiers

Nous faisons une bibliothèque npm avec des composants communs qui ne sont pas censés être utilisés tous en même temps et énervés par ce problème lors de la compilation AoT, bon sang... La seule solution atm consiste à créer une sorte de UnusedComponentsModule dans le projet hôte - tout simplement ridicule ! Vous avez également besoin NO_ERRORS_SCHEMA ou il jurera sur d'autres composants qui peuvent être utilisés dans vos composants inutilisés et si vous les déclarez, alors vous rencontrez un autre problème où vous ne pouvez pas déclarer le même composant dans deux modules (lié à # 10646).

Mon module actuel :

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 {
}

Cela devrait vraiment être un avertissement. J'essaie également de partager une base de code et je rencontre ce problème de composants ne faisant pas partie d'un ngmodule.
Le problème ici est exactement comparable à une variable inutilisée qui n'est pas une erreur ; tout au plus c'est un avertissement.

C'est facile quand c'est votre code. Quand c'est un problème de bibliothèque angulaire NPM (du code mort), alors c'est vraiment chiant :)

Quelqu'un peut-il expliquer pourquoi il ne peut pas s'agir d'un avertissement au lieu d'une erreur ?

Dans mon cas, je veux juste extraire les langages de préférence à partir de composants connectés à ngModule et ignorer ceux qui ne le sont pas. J'ai un dossier d'application principal avec des composants de base et des dossiers spécifiques à l'application qui remplacent parfois les composants de l'application principale lorsque j'essaie d'extraire un tel composant remplacé avec xi18n, il génère une erreur Cannot determine the module for class... qui, dans mon esprit, pourrait être simplement ignorée et extraction pourrait être poursuivi sans utiliser ce composant inutilisé.

Une chose à laquelle je peux penser que cela pourrait être un problème est que j'utilise toujours cette classe qui est définie dans ce fichier de composant défectueux comme base pour créer le composant remplacé, il doit donc être compilé mais je n'ai tout simplement pas besoin de ce composant cause d'annotation car vous ne pouvez pas l'utiliser dans le composant remplacé. Au moins, je pense que vous ne pouvez pas car je dois recréer ces annotations dans des composants dérivés pour les faire fonctionner.

@Xesenix au moins, cela devrait être une option. Comme determineModule = false / true. Maintenant, ce sont les bananes.

Je reviendrai le 01/11/2017.

Je répondrai à votre message après mon retour.
En cas d'urgence, veuillez envoyer une copie de votre e-mail pour
questions techniques à [email protected] , sinon à
[email protected]. Un autre employé regardera alors votre e-mail
J'accepte.

Remarque : Il s'agit d'une réponse automatique à votre "Re :
[angular/angular] Compilation Angular2 AOT - "Impossible de déterminer le module
pour la classe (... de nombreux composants inutilisés)" (#13590)" envoyé le
23/10/2017 08:13:17.

Il s'agit de la seule notification que vous recevrez pendant
cette personne est absente.

Comment cela n'est-il toujours pas résolu près d'un an plus tard ? Je m'arrache les cheveux pour faire fonctionner AOT, mais ce problème me fait heurter un mur de briques.

Merci @rahul-sivalenka-wtc pour la solution !
J'ai réussi à résoudre mon problème en excluant "**/*.mock.ts" dans mon tsconfig.app.json comme vous le décrivez ❤️

Content d'avoir pu aider 😊

J'ai également rencontré le problème. Mais pour moi, il me semble que j'ai juste mis à tort le chemin d'importation de dodule

des solutions ? (impossible de déterminer le module pour le composant angulaire 5)

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

Cela devrait probablement être de severity3: broken . Pour ceux d'entre nous qui ont plusieurs cibles de build et des dépendances polymorphes (dont de nombreux cas d'utilisation ont été présentés ci-dessus), ce problème empêche les builds de fonctionner sans une configuration de build compliquée et folle.

une bonne solution pour ce problème encore? IgnoreModule n'est qu'une solution de contournement mais pas une très bonne solution à ce problème. changer l'erreur en avertissement serait génial!

Notre solution consistait à ajouter une fonction transform à @ngtools/webpack qui transmet les fichiers via le prétraitement et les composants ifdef en fonction de divers paramètres de compilation. Très, très laid, mais fonctionnel.

Essayez d'importer d'abord toutes les dépendances angulaires dans app.module.ts, puis importez les composants.

` ---------------- Première importation des modules de dépendance -----------------------
import { BrowserModule } de '@angular/platform-browser' ;
import { CommonModule } de "@angular/common" ;
importer { NgModule } de '@angular/core' ;
import {RouterModule, Routes} de '@angular/router' ;
importer { HttpModule } de '@angular/http' ;
import { ReactiveFormsModule } de '@angular/forms' ;
import { BrowserAnimationsModule } de '@angular/platform-browser/animations' ;

--------------Puis Importer les modules de service ------------------------

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

----------------------- Enfin importer les modules de composants ----------------------- -

importer { AppComponent } à partir de './app.component' ;
import { HeaderComponent } de './components/header/header.component' ;
import { CareerComponent } de './components/career/career.component' ;
importer { HomeComponent } à partir de './Components/home/home.component';`

D'une manière ou d'une autre, cela a résolu l'erreur de compilation AOT en lançant Impossible de déterminer le module pour la classe --- en mode production

@KarthikSamyak , ce problème ne concerne pas les personnes qui ont des cours qui DEVRAIENT être dans un module. Il s'agit de ceux d'entre nous qui ont des bibliothèques de composants, qui sont délibérément exclues de tous les modules. Ce sont des codes inutilisés qui doivent être ignorés par le compilateur. Au lieu de cela, le compilateur génère une erreur irrécupérable lorsqu'il les découvre.

Cela devrait vraiment être un simple changement pour transformer cette erreur en avertissement, mais pour une raison quelconque, cela a pris PLUS D'UN AN et a été récemment déplacé de pri_col1 à pri_col2 sur la feuille de route.

Je suis de plus en plus frustré par l'équipe Angular pour son absence totale de réponse à ce problème. Notre société a finalement renoncé à utiliser entièrement les bibliothèques de composants, choisissant plutôt de copier les fichiers manuellement. C'est loin d'être idéal, car nous avons maintenant des problèmes avec des composants presque identiques, mais non partagés.

Équipe angulaire, si vous lisez encore plus ce problème, ajoutez simplement un paramètre de compilateur pour "ignoreUnusedComponents" et laissez-nous continuer à utiliser ce framework.

Ok, j'ai trouvé l'endroit https://github.com/angular/angular/blob/master/packages/compiler/src/aot/compiler.ts#L605 @tbosch hé, pouvez-vous aider ici et dire comment faire cela pour être un avertissement correctement? Impossible de voir les avertissements lancés dans ce compilateur AoT, uniquement les erreurs. Une option de compilation peut être ajoutée, comme suggéré ci-dessus.

Ce problème est une douleur sur les projets complexes. Mon cas particulier est https://github.com/angular/angular/issues/13590#issuecomment -331820496

Notre cas d'utilisation est le même. Nous voulons avoir une bibliothèque de modules/composants pour créer des applications très facilement et avoir la possibilité de remplacer/étendre les applications impaires en cas de besoin.

Nous rencontrons également des problèmes dans l'autre sens : si nous voulons remplacer un composant 1x dans un module, nous créons un nouveau module et importons les composants que nous voulons encore :

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 { }

L'erreur est : `HeaderComponent est déclaré dans 2 modules : lib/module.ts et app/module.ts
Être un avertissement à la place nous permettrait au moins d'avancer :(

Je viens de réaliser - Joyeux anniversaire à ce numéro :)

Un an plus tard, et nous ne pouvons toujours pas changer cela en avertissement. Ridicule.

Littéralement, je viens également de rencontrer ce problème. Le compilateur essaie d'extraire une maquette qui n'est utilisée que dans les tests et échoue car il ne fait pas partie du module principal. S'il sait qu'il n'a pas besoin du fichier, il devrait s'agir tout au plus d'un avertissement.

Veuillez corriger cela. Faites-en un avertissement !
Mon expérience générale avec la construction angulaire 5 aot est moins que stellaire.

Après quelques discussions https://gitter.im/angular/angular?at=5a551f565a9ebe4f756843b2 , nous sommes arrivés à la conclusion que nous devons créer un composant par module car il semble que ce module ne soit qu'un contexte de compilation et non un moyen de collecter des éléments ensemble. .

Cela prend la taille d'un livre d'histoire.

@Xesenix ... le contexte et l'organisation sont 2 parties d'un tout.

Juste au cas où quelqu'un serait toujours bloqué avec cela, vous pouvez exécuter ce script en tant que script de post-installation comme solution de contournement

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

Le compilateur angulaire utilisera la sortie de tsconfig, donc changez _tsconfig.app.json_ pour exclure les fichiers que vous ne voulez pas inclure
par exemple
"exclude": [ "test.ts", "**/*.spec.ts", "**/*.mock.component.ts", ]

@andela-andrewmakenzi cela a déjà été suggéré, plus loin dans ce gigantesque chat (absolument aucune honte à ne pas lire tout). Cependant, des problèmes surviennent si vous dépendez d'un composant dans une bibliothèque qui utilise des fichiers baril (index.ts). Si vous importez un composant à partir d'un fichier baril, le compilateur essaie de charger tous les composants référencés dans ce fichier baril et se plaindra qu'ils ne sont pas dans un module. Cela rend difficile l'empaquetage de bibliothèques de composants réutilisables, ce qui est essentiellement tout l'intérêt de l'architecture des composants en premier lieu.

Votre solution fonctionne très bien pour les personnes qui ont des composants fictifs et qui obtiennent cette erreur lorsqu'elles n'exécutent pas de tests. Mais si votre organisation (comme la mienne) a essayé de créer une bibliothèque de composants communs et d'extraire uniquement ceux dont nous avons besoin pour un projet donné, l'exclusion de TSC ne vous aidera malheureusement pas.

@andela-andrewmakenzi : Votre suggestion semble aider pour l'instant, le problème précédemment est que j'ai un composant pour le test unitaire en tant que ( .spec) et je ne voudrais pas qu'il soit inclus pour AOT-build (et peut-être un composant fictif qui Je n'aimerais même pas l'avoir dans ma projection) Peut-être que cela a été résolu d'une manière ou d'une autre dans la version ultérieure d'Angular, je pense :)

Mais mon cas était que j'ai beaucoup de nouveaux composants qui n'étaient même pas référencés dans NgModule donc pour l'instant nous devons avoir une convention de nom pour cela et les exclure dans tsconfig.json , ce qui n'est pas très agréable pour le moment

C'est vraiment ridicule. Nous avons un module NPM partagé exportant quelques tuyaux/directives et à moins que vous n'importiez TOUT, il échoue avec cette erreur stupide. Il devrait vraiment être changé en avertissement et il ne devrait pas casser la compilation.

À mon avis, chaque composant devrait être dans son propre NgModule . Ce n'est pas si effrayant de créer un autre NgModule pour chaque composant. (Comme ce que @angular/material a fait)

Je pense que c'est vraiment un problème virtuel. Nous ne voyons pas non plus de raison d'avoir quoi que ce soit à mi-chemin. Pas un NgModule , pas un package, pas en dehors de l'arborescence de l'application ... quelque chose qui ressemble à du code mort.

Donc, avec le nouveau @angular/cli (1.7.0+), même IgnoreModule ne contourne pas ce problème.

À mon avis, chaque composant devrait être dans son propre NgModule

Essayez-vous même d'écrire des tests unitaires? Ce bogue rend la création d'assistants de test un peu problématique.

@sarunint Dans des applications de taille entreprise comme celle pour laquelle j'ai initialement ouvert ce ticket, il s'agirait de centaines de modules, avec des importations très compliquées afin de gérer les directives et composants dépendants. Cela a une solution très simple : si le compilateur ne trouve pas de module pour un composant, lancez un avertissement et supprimez-le dans l'arborescence.

La vraie raison pour laquelle c'est si ennuyeux est le fait que les limes cylindriques deviennent plus un danger qu'une aubaine. Il est pratique de centraliser vos importations, mais pas si vous vous engagez à inclure chaque composant exporté dans chaque application qui utilise votre bibliothèque.

@dborisenkowork Je ne sais pas si vous ne l'avez pas vu (ou si cela ne fonctionne pas pour votre cas d'utilisation) mais la solution fournie par @rahul-sivalenka-wtc fonctionne parfaitement.

Quelqu'un est-il récemment passé d'angular 4 à angular 5 et a-t-il remarqué que certains de leurs composants déclarés dans les modules génèrent cette erreur?

@novologic-clay quelle erreur ? Le fil est long, faites-vous référence à l'erreur d'origine
Compilation Angular2 AOT - "Impossible de déterminer le module pour la classe (... de nombreux composants inutilisés)" ?

@andela-andrewmakenzi Oui et non. C'est la même erreur imprimée lors de la tentative de compilation, mais le composant dont il se plaint est très certainement inclus dans un module. Je migre de 4.3.6 à 5.2.4, et je n'obtenais pas cette erreur pour ce composant particulier parce que j'ai mis à jour ma version d'angular, et j'ai fait une compilation AOT sur 4.3.6 juste avant de commencer la migration en tant que test de fumée .

@novologic-clay pouvez-vous partager vos erreurs de console ?

... l'objectif final devrait être d'utiliser l'option $ tsconfig.json "noUnusedLocals": true qui élimine tout ce qui n'est pas utilisé.

@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.

Il s'agit d'une application d'entreprise et il existe des dizaines de couches de modules et d'importations, mais c'est le code qui déclare réellement le composant :

**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 { }

Il convient également de noter que lorsque j'exécute cette application dans ng serve, le composant fonctionne correctement.

Les faux composants utilisés par les tests de nombreux composants réels ne doivent pas se trouver dans un module ; Ils sont juste inclus dans TestBed des composants testés.
Cette erreur est stupide. S'il vous plaît, résolvez cela car c'est pendant un an.

supprimez "l'exportation" afin que ts ne le prenne pas dans la construction.

@tony-kaplan Vous ne pouvez pas faire cela si vous n'avez pas de paramètres locaux inutilisés dans votre tsconfig, ni si vous souhaitez utiliser le code dans des cas de test ou similaires.

Mon Dieu .... vraiment que personne de l'équipe de base n'a trouvé de solution appropriée pour cela?
J'utilise l'option exclude pour l'instant, mais c'est toujours une solution temporaire. Je ne peux pas penser à quelque chose qui fonctionnerait pour toutes les situations... mais j'en ai vraiment besoin...

@gabrielalan La solution simple est de transformer cette erreur en avertissement. La meilleure solution consiste à ajouter un drapeau qui vous permet de traiter cela comme un avertissement ou une erreur. Ce n'est pas un manque de solutions, c'est un manque de mise en œuvre de l'une ou l'autre.

Oh mec! Voilà pour un cadre d'entreprise...

@atom-morgan de quelle solution de contournement parlez-vous ?

@netlander Celui-ci

Vraiment, je ne peux rien faire à propos de l'erreur "Impossible de déterminer le module pour la classe DaterangepickerDirective" ?

Quelqu'un m'aide aussi ? Après ce méga post !

Je ne suis pas d'accord pour ajouter dans le tsconfig.app.json de nouvelles exclusions à cette directive ! Comment puis-je compiler avec --aot param sans ce problème ?

Mon cas d'utilisation https://github.com/angular/angular/issues/23475
Je crée une bibliothèque de validateurs et je ne veux pas créer de module pour chaque directive de validateur, tout ce que je veux, c'est juste pouvoir regrouper les directives de validateur dans le package npm afin que l'utilisateur puisse installer et importer uniquement les validateurs dont il a besoin dans NgModule. De plus, je ne veux pas créer un module pour tous les validateurs car ils seront tous regroupés dans le bundle final, ce qui représente un énorme gaspillage de taille.

Je suis heureux de créer PR pour résoudre le problème.

@anjmao c'est incroyablement similaire à la raison pour laquelle j'ai ouvert ceci en premier lieu. Comme solution de contournement pour une petite bibliothèque, nous avons constaté que cette erreur ne se produit pas si vous n'utilisez pas de fichiers baril (index.ts). Il semble que si vous importez 1 composant/directive à partir d'un index, il essaie de trouver un module pour toutes les autres exportations du fichier d'index.

Évidemment, je pense toujours que cela devrait être un avertissement, car les fichiers baril sont super pratiques. Cependant, si votre cas d'utilisation ne peut pas attendre une autre année pour ce correctif, vous pourrez peut-être le contourner comme ça.

Solution de contournement que j'utilise pour ma bibliothèque partagée de composants/directives/tubes : créez un module factice simple qui référence toutes les déclarations de classe. Vous n'avez pas besoin d'utiliser ce module dans vos vraies applications, il doit juste exister sur le disque. Ex:

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

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

Y a-t-il une raison pour laquelle nous n'avons toujours pas résolu ce problème ?

La solution "En faire un avertissement" n'est-elle pas adéquate ? Un membre de l'équipe de base peut-il commenter cela ?

Dans mon cas, les choses allaient bien avec NG 5, CLI et AOT. Mais après la mise à niveau vers NG 6, j'obtiens une erreur similaire pour un composant inutilisé. En fait, le composant est utilisé via un service injecté dans l'autre composant. J'ai de nombreux composants similaires construits et utilisés de la même manière. Mais un seul a un problème de mise à niveau vers les dernières NG CLI 6.0 et 6.0.1

Et il s'est avéré que, dans l'une des références, j'ai la référence du fichier dans la mauvaise casse. J'ai un index.ts pour exporter tous les composants dans le même répertoire. j'ai eu
export * from './dateTimePicker.component'
alors qu'il aurait dû être :
exporter * de './datetimePicker.component' ;

Apparemment, NG CLI 6 est plus restreint pour la casse, même sous Windows, tandis que NG CLI 1.x est un peu relaxant.
Évidemment, une telle restriction est bonne et correcte, donc la même base de code pourrait bien fonctionner sous Linux, qui est sensible à la casse par défaut.

Un autre cas d'utilisation pour ceci:

Typescript vous permet de configurer plusieurs chemins de résolution avec la variable paths dans tsconfig.json . Ex:

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

Vous permettant d'importer des choses comme ceci :

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

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

Si vous générez un composant à l'intérieur src-gen que le développeur peut "écraser" en en créant un autre dans le dossier src , la même erreur commence à se produire avec le composant (maintenant inutilisé) à l'intérieur src-gen (qui ne devrait pas avoir besoin d'être supprimé, car il pourrait être étendu par l'overrider).

Autre cas d'utilisation potentiel :

Composants spécifiques à l'environnement. Je les dépouille pour la production.

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

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

J'ai réussi à faire fonctionner tout le reste avec des composants spécifiques à l'environnement et c'est ce qui m'arrête. 😪

Nous sommes confrontés à ce problème lors de la mise en œuvre d'un mécanisme de personnalisation de la construction (les composants sont échangés pour différents projets CLI angulaires) qui ressemble assez au scénario décrit par @tiagodws (y compris l'extension du composant d'origine).

Existe-t-il une mise à jour/avis d'une équipe centrale sur cette question ?

Plus d'un an après avoir ouvert ce numéro, ma nouvelle approche consiste à minimiser l'utilisation des fichiers baril. Si vous utilisez partout des chemins TS tels que ~components/button/component dans vos importations, les importations inutilisées sont ignorées. Si ce composant inutilisé est référencé dans un fichier baril, il sera lancé.

Ce n'est toujours pas génial pour les bibliothèques réutilisables, car vous devez accéder à tous les composants de la bibliothèque avec des chemins plus longs, au lieu de simplement importer à partir de ce niveau supérieur de bibliothèque. Pourquoi, oh pourquoi cela ne peut-il pas être juste un avertissement ?

Il semble également que cela pourrait être aidé par (ou du moins lié à) l'agitation de l'arborescence, où tout code non spécifiquement inclus dans un module est exclu du paquet final.

l'option d'exclusion ne fonctionne pas pour un tuyau factice :

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

Mon tsconfig.app.json a exclu ce fichier :

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

Cependant, lorsque je lance ng-xi18n --i18nFormat=xlf2 --outFile=./assets/i18n/messages.xlf, il se plaint toujours :

Impossible de déterminer le module pour la classe MockTranslatePipe dans src/test/translate.service.mock.ts ! Ajoutez MockTranslatePipe au NgModule pour le réparer.

Mon problème était que j'avais le nom d'une classe dans 2 composants différents en faisant un copier-coller lol ! Plus tard, même erreur pour ne pas s'en soucier. Les bonnes pratiques font des gars parfaits ! les coups...
Signature : Satoshi Nakamoto : v

Semblable à @yuezhizizhang , j'ai toujours ce problème, même après avoir ajouté un glob pour les simulacres au chemin tsconfig.app.json exclude .

Il est presque exaspérant que cela n'ait pas été résolu près de deux ans après le ticket initial ; il s'agit d'un cas d'utilisation courant qui est BREAKING builds. Lors de l'écriture de tests, le développeur devrait idéalement créer des simulations pour les canaux, les services, etc., à moins que. Si vous choisissez de le faire, votre build se casse. Si ce n'est pas le cas, vos fichiers de spécifications font référence aux vrais composants/tuyaux/etc, ce qui conduit à des tests très étroitement couplés.

Quelqu'un de l'équipe Angular pourrait-il suggérer comment contourner cela? La création d'un module factice fourre-tout pour les simulations est-elle vraiment la seule option ? C'est un mauvais piratage, plutôt que quelque chose que nous devrions accepter comme meilleure pratique.

le problème persiste. J'ai également ajouté le fichier que je souhaite ignorer la construction (classe abstraite) à la section d' exclusion de tsconfig.app.json et j'obtiens toujours :

Impossible de déterminer le module pour la classe MapElementBaseComponent dans .../map-elements/map-element-base.component.ts ! Ajoutez MapElementBaseComponent au NgModule pour le réparer.

Je me suis débarrassé de ce problème après avoir revérifié les importations

ср, 14 novembre. 2018 г., 15:13 Daniel Groh [email protected] :

le problème persiste. J'ai également ajouté le fichier que je souhaite ignorer la construction
(classe abstraite) à la section d' exclusion de tsconfig.app.json et moi
Encore obtenir:

Impossible de déterminer le module pour la classe MapElementBaseComponent dans
.../map-elements/map-element-base.component.ts ! Ajouter MapElementBaseComponent
au NgModule pour le réparer.


Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/angular/angular/issues/13590#issuecomment-438641324 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AQb6kpWdkakUF8JVvea8Hy42tAnTKTuzks5uvAjvgaJpZM4LSAwS
.

Lorsque TypeScript strict, l'importation angulaire, dans la compilation AOT, n'utilise pas les composants d'une bibliothèque et lance cette erreur... Vérifier les composants/modules non utilisés n'a pas de sens...

image

En supprimant le dossier de la bibliothèque où se trouvent le module et les composants non utilisés, l'application se lance en toute rigueur - mais cela n'a sûrement aucun sens de supprimer ce dossier manuellement

Cette erreur est absolument ridicule. J'avais un module qui spécifiait des composants dans un objet, comme ceci :

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

puis j'ai essayé d'alimenter le module avec declarations: Object.values(landingComponents) , entryComponents: Object.values(landingComponents) .

Devinez quoi ... le compilateur AOT a besoin de voir les composants répertoriés dans un tableau ... sinon si je le passe d'une autre manière, j'obtiens cet horrible "Impossible de déterminer le module pour la classe".

Autant j'aime Angular, autant le compilateur AOT ressemble à une soupe chaotique d'incantations magiques.

Cela a été dit plusieurs fois, mais la solution est de 1 composant par module pour cela et je ne sais pas si vous avez remarqué des relations publiques à Angular, mais cela a été fusionné récemment et pourrait intéresser ce sujet : https://github.com/ angulaire/angulaire/tirer/27481

Ce numéro fête ses 2 ans aujourd'hui 🎉

Pourtant, pas même un mot de l'équipe principale expliquant pourquoi cela ne pouvait pas être juste un avertissement.

@tiagodws lol depuis combien de temps attends-tu pour poster ça ? Avez-vous défini un rappel ?

Juste un FYI
Mon problème était le même que https://github.com/angular/angular/issues/13590#issuecomment -389113560
Les importations sont apparemment sensibles à la casse en mode AOT

@peterdeme ... JavaScript est sensible à la casse (et les chemins en tant que chaînes sont identiques ... = basé sur Linux, pas sur Windows).

Hé les gars, je viens de revenir pour une célébration tardive de l'âge de 2 ans. Il y a beaucoup de discussions croisées sur les causes possibles pour les gens, y compris les sections include et exclude de tsconfig.json , donc je veux juste clarifier quel est le problème fondamental pour ce fil.

Si vous créez une bibliothèque de composants réutilisables et ajoutez des fichiers baril ( index.ts ) pour faciliter les importations, le compilateur Angular s'arrêtera lorsque vous en utiliserez un. En effet, dès que vous importez quoi que ce soit à partir de ce fichier baril (par exemple, @shared/components ), il tentera de trouver le module pour CHAQUE COMPOSANT. Même si vous spécifiez les composants spécifiques que vous voulez (par exemple import { SharedToastComponent } from '@shared/components'; ), le compilateur cherchera toujours le module pour chaque composant exporté et lancera une erreur (pas un avertissement) sur les composants manquants.

Évidemment, il existe des solutions de contournement.

  1. Arrêtez d'utiliser des fichiers baril. Cela devient rapidement désordonné, car chaque composant doit être entièrement spécifié
  2. Utilisez un ExtrasModule et n'utilisez le module nulle part. Cela fonctionne bien pour les personnes qui ont uniquement des composants nécessaires pour les tests, mais pas si bien pour les personnes qui cherchent à extraire d'une bibliothèque de composants

Cependant, étant donné que l'utilisation de l'une ou l'autre de ces solutions de contournement donne exactement le même code de sortie après le secouage de l'arborescence, il est évident que les autres composants n'ont PAS BESOIN d'être inclus dans un module utilisé. Tout ce que je demande avec ce problème vieux de 2 ans, c'est de transformer cette erreur en un avertissement plus approprié. Cela a du sens, puisque la compilation réussirait toujours si elle était autorisée à continuer.

Espérons qu'en 2019, l'équipe Angular fera quelque chose à propos de ce problème très ancien et très ennuyeux. 🤞

@swimmadude66 ... vous n'avez pas mentionné la façon de créer un vrai module lib et de l'ajouter à une application angulaire via tsconfig.json ... comme: "paths": {"ng-demo": ["./packages/ng-demo/src/index.ts"]} et de l'utiliser via l'importation comme import { DemoModule } from 'ng-demo'; . De cette façon, il n'est plus nécessaire de publier la lib dans un référentiel npm public/privé tout en respectant le rôle natif de ce module lib. Cela fonctionne donc de manière transparente dans votre application et vous n'avez aucun problème.

Avoir une erreur sur chaque talon de composant est la chose la plus ennuyeuse. Tout le monde teste/écrit des spécifications, n'est-ce pas ? Ainsi, les erreurs de stub de composant devraient affecter tout le monde. Je ne dis pas que le problème du canon est moins ennuyeux. Je dis juste que tout le monde ne fait pas les barils. Mais tout le monde devrait faire des spécifications. Le problème des spécifications devrait donc être la plus grande motivation de l'équipe principale pour résoudre ce problème. Il est actuellement étiqueté "Fréquence basse" mais devrait être "Fréquence élevée" car toute personne effectuant des tests unitaires rencontrera ce problème.

Ce n'est même pas cohérent dans AOT. Angular CLI ne donne pas d'erreurs lors de l'exécution avec serve (qui utilise par défaut AOT) mais donne des erreurs d'exécution avec build.

Je comprends que ce n'est pas le repo Angular CLI, mais le comportement qui l'entoure est certainement étrange.

Même avec la solution de contournement consistant à créer un module fictif, la "construction ng" échouera si un rédacteur de test d'unité d'interface utilisateur oublie d'ajouter un seul composant fictif à un module fictif.

Ci-dessus signifie que les tests unitaires de l'interface utilisateur sont actuellement un élément de risque pour le pipeline de déploiement CI/CD !

Voulons-nous vraiment devoir expliquer aux personnes situées plus haut dans la chaîne alimentaire que les testeurs unitaires angulaires peuvent casser des versions de déploiement entières avec une seule omission triviale ? Nan. Les personnes qui gèrent les développeurs Angular et qui prennent des décisions sur le framework à utiliser pour le prochain projet ne devraient pas se poser de questions sur ce genre de choses.

Comme palliatif : pourquoi ne pas simplement rendre l'erreur qui apparaît dans "ng build" plus informative pour les rédacteurs de tests : c'est-à-dire ajouter un texte supplémentaire à l'effet de "s'il s'agit d'un composant fictif utilisé dans les tests : ajoutez-le à un module fictif dans ce fichier selon (cette URL)"

Comment vos tests unitaires d'écriture de développement angulaire amicaux moyens sont arrivés ici :

a) À mon humble avis, il s'agit d'une pratique de code DRY pour créer un fichier "helper" pour placer des composants fictifs, des services, etc. que tous les fichiers .spec utilisent. Cependant, cette pratique exécute le testeur en plein dans ce scénario de bogue.

b) Tous les fichiers .spec peuvent importer ce fichier "helper" sans avoir besoin d'un "module fictif" qui n'a aucun rapport avec le code de test réel. Les composants fictifs sont utiles tels quels, sans appartenance à un module fictif qui n'a aucun rôle dans l'environnement de test d'une spécification.

Bien sûr, la solution de contournement est triviale ... mais le simple fait de trouver ce bogue via la recherche Google, de lire et de digérer le fil de discussion et des solutions de contournement utiles ne l'était pas.

J'ajoute juste ceci à la fin du fichier d'aide qui contient les composants fictifs (entre autres):

/*
  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 {}

Notez que le fichier ci-dessus est en réalité assez volumineux... le "MockTestModule" est enfoui à la fin du fichier d'aide...

... J'espère que nous n'aurons pas à écrire une entrée package.json pour "ng build" qui intercepte l'appel et insère un message de console "hé les testeurs d'unités d'interface utilisateur, avez-vous ajouté votre composant fictif au module fictif ?" coup de coude.

Voici ce qui a résolu le problème pour moi. Ma structure est la suivante :

├── 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

En icons.module.ts j'avais :

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 {}

Les index.ts avaient :

export * from './icons.module';

Je suppose que le problème était que le compilateur n'avait pas analysé les modules icon et icon-indicator avant de rencontrer les composants correspondants et a donc lancé l'erreur Cannot determine the module for class . Ce projet est ng 5. Je n'ai eu l'erreur que lors de sa consommation dans un projet ng 7.

La solution consiste à déplacer les exportations d'un niveau vers le bas. J'ai donc supprimé l'instruction d'exportation dans icons.module.ts et les ai déplacées vers :

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

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

et ajusté index.ts :

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

J'espère que cela aide quelqu'un.

Je pense que le nouveau moteur de rendu Ivy résoudra pas mal de problèmes avec AOT. Comme vous pouvez le voir sur les demandes d'extraction et les problèmes, l'équipe angulaire se concentre sur le lierre, il est donc inutile de faire quelque chose à propos de ce problème sur angulaire 6.

Je pense que le nouveau moteur de rendu Ivy résoudra pas mal de problèmes avec AOT.

J'aime entendre cela sur chaque numéro.

J'ai aussi ce problème avec angular 7.2.0 et 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.

Par exemple, j'ai un TranslatePipe et un TranslatePipeMock dans mon Shared Module . TranslatePipe est inclus dans le module, le mock pipe ne l'est pas.
translate.pipe.mock.ts est destiné aux tests unitaires, je peux donc simplement importer ce fichier dans chaque test unitaire.

Mais maintenant ma construction échoue
ng build --prod

Comment réparons nous ça?

Atm j'ai une solution de contournement qui le résout

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

Il est difficile de déterminer l'état actuel de ce problème à partir d'un bref examen des commentaires. Je suis d'accord que c'est un problème (mauvaise conception). Quel est le plan pour y remédier ? Est-ce facile ou difficile ?

@rrmayer le statut de ce problème est très probablement simplement "attendez le lierre", comme pour presque tous les problèmes "actuels".

Nous voulons juste que cela passe de « erreur » à « avertissement », afin que nos projets se compilent réellement... Est-ce si difficile ?

@ Terrafire123 ... il pourrait y avoir de nombreuses relations avec les outils de test ou de construction par exemple, qui sont basées en fait sur le fait que ce cas conduit à l'erreur, donc le changement de l'avertissement pourrait être un problème sérieux.

Je n'ai aucun espoir que ça va être corrigé pour le compilateur actuel :D

Peut-être devrions-nous au moins avoir la possibilité d'afficher une erreur ou un avertissement. Les constructions se cassent parce que les composants ne font pas partie d'un module à dessein sont assez ennuyeux.

Les importations inutilisées peuvent provoquer cette erreur.

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

Il semble que le mot-clé 'export' à côté de la classe détermine d'une certaine manière que la classe à laquelle le décorateur @Component est appliqué doit être incluse dans un module. Que vous importiez la classe du composant et que vous la déclariez directement dans les tests ou que vous la déclariez dans CoreMocksModule, par exemple, puis que vous importiez le module, tout cela n'a pas d'importance.

Il y a une solution de contournement cependant! Disons que notre composant stub est déclaré comme ceci :

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

Nous devons supprimer le mot-clé 'export' mais d'une certaine manière nous devons toujours exporter le composant pour l'utiliser dans le module test/test. Fais-le comme ça:

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

export default UserStubComponent;

Maintenant, partout où vous importez le stub, nous devons éviter les crochets comme suit :
import UserStubComponent from 'path'

Esperons que ça marche. Pour moi, cela résout les problèmes de compilation AOT.

Dans mon cas, je l'ai corrigé. Le problème venait du boîtier. J'ai utilisé des majuscules pour les dossiers, mais l'importation automatique du code VS a importé le chemin en minuscules.

@ renilbabu03 JS est sensible à la casse.

Dans mon cas, je l'ai corrigé pour mes tests unitaires, où je me suis moqué du tube de traduction.

J'ai changé le export class en default export :

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;

Des correctifs pour cela?
J'ai essayé export default <class> mais lorsque j'exécute ng serve --aot , une erreur s'affiche : Valeur inattendue 'null' exportée par le module .

C'est très frustrant.

@redplane Pourquoi voulez-vous faire ça ? Je veux dire l'exportation default .

À moins que je import un actif exported , pourquoi Angular se soucie-t-il de l'existence du fichier?

Le plus souvent, je refactorise un composant ou supprime des composants et je souhaite simplement commenter les références de composants obsolètes, comme je l'ai fait à l'époque de CommonJS. Ce serait assez sûr puisque je n'utilise jamais de fichiers baril parce que j'ai été brûlé trop de fois sur ce front, et avoir Angular me force à m'engager à supprimer physiquement les actifs de mon projet est tout simplement inacceptable quand je suis au plus profond de moi une phase de prototypage...

Je suis coincé dans Angular 6 parce que je suis le seul développeur à travailler sur ce projet et ce serait un enfer de refactoriser les choses pour se mettre au niveau des derniers outils stables au milieu d'avoir à livrer de nouvelles fonctionnalités... donc au tout au moins, ce serait formidable si Angular 6+ pouvait être corrigé avec un indicateur de compilateur pour désactiver ce comportement ...

Dans mon cas, j'ai une configuration de projet de bibliothèque angulaire. Dans l'un de mes composants à l'intérieur de la bibliothèque, j'ai déclaré quelques énumérations, afin d'utiliser ces énumérations dans mon projet d'application que j'importais avec un chemin relatif vers le répertoire des projets dans la racine de mon application.

C'est la raison pour laquelle le compilateur angulaire voulait que mon composant de bibliothèque soit déclaré dans l'un des ngModules du projet d'application.

Pour résoudre cette erreur, je dois déclarer mes énumérations dans le fichier public-api.ts et les utiliser dans un projet d'application avec une importation directe depuis la bibliothèque et non avec un chemin d'importation relatif.

Par exemple:
Nom du projet de bibliothèque : components-lib
Nom du projet d'application : application de démonstration

Pour utiliser toutes les interfaces, classes, énumérations , etc. déclarées dans le projet de bibliothèque, importez-les avec un chemin direct :

importer { SearchEnum } à partir de 'components-lib' ;

et ne fais pas
import { SearchEnum } de '../../../projects/components-lib/path-to-your-component' ;

J'espère que cela aidera quelqu'un à l'avenir, car j'ai passé des heures à le trouver moi-même.

Ayant un problème pour maintenir la compatibilité d'une bibliothèque construite avec ng 9 que je voulais que les personnes exécutant ng 8 puissent utiliser.

Je propose via la bibliothèque des classes utilitaires sur lesquelles vos composants peuvent s'étendre. Dans cette chaîne de classes parentes, certaines d'entre elles sont abstraites et avec ng 9 doivent avoir un @Directive({ selector: 'random' }) pour être compatibles avec ng 8.

Donc j'ai failli m'en tirer... MAIS :

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.`

Je n'expose aucun module au sein de la bibliothèque, les gens sont juste censés s'étendre sur les cours que nous proposons. Mais je ne veux pas qu'ils aient à importer les classes parentes dans leurs modules (cela n'aurait aucun sens).

Donc je suis coincé et je vais juste couper une version de changement de rupture obligeant les gens à passer à ng 9 au lieu d'avoir une rétrocompatibilité

Salut à tous, désolé pour le silence sur ce sujet.

ngc dans View Engine, de par sa conception, génère des fichiers ngfactory pour chaque composant de la "compilation", c'est-à-dire l'ensemble complet des fichiers TS définis par votre tsconfig. C'est ainsi que TypeScript
lui-même fonctionne - il compile tous les fichiers définis par un tsconfig. ngc fait juste un traitement supplémentaire en plus de cela.

Donc, si un @Component est présent dans cette compilation et que ngc peut le voir (ce qui signifie qu'il est de niveau supérieur et exporté), ngc essaiera de le compiler. Il n'y a pas d'autre moyen de contourner cela que de s'assurer que ngc ne compile pas le fichier qui déclare le composant en premier lieu.

La bonne façon de procéder consiste à définir la portée de votre fichier tsconfig. Par exemple, vous pouvez avoir un tsconfig de niveau supérieur pour votre éditeur, qui inclut tous les fichiers, puis un tsconfig.app.json pour la compilation de votre application en particulier, qui hérite de la configuration de l'éditeur et exclut les fichiers de spécification. Seule la configuration de l'application serait compilée avec ngc.

Les projets (chaque tsconfig est un "projet") doivent être structurés de telle sorte qu'un composant et son module soient toujours compilés ensemble.

Dans Ivy, les mêmes règles s'appliquent encore largement, avec quelques petites différences :

  • Par défaut, Ivy essaiera de compiler _tout_ @Component , qu'il soit exporté ou non.
  • Ce n'est plus une erreur, dans Ivy, d'avoir un composant sans module. Cependant, vous obtiendrez toujours des erreurs de vérification de type de modèle si ce composant essaie d'utiliser d'autres composants/directives dans son modèle, car sans module, rien d'autre ne sera visible pour ce composant.
  • Il est possible de dire au compilateur Ivy d'ignorer un composant ou un module particulier et de le laisser jusqu'à l'exécution, en ajoutant un indicateur jit: true au décorateur.

@alxhub Je suis content d'apprendre que ce n'est plus une erreur !

Je comprends que ngc essaiera de compiler tout ce que tsc ferait, et que tsc compilera tout ce qui relève de sa portée. Cela étant dit, l'exigence qu'un composant soit ajouté à un module est à 100% une préoccupation angulaire, donc le retirer de la portée de votre projet dactylographié donne l'impression de donner un coup de pied dans la boîte. De plus, les modèles tels que les fichiers baril étant courants, il peut être difficile de supprimer véritablement un seul fichier de la compilation, sans le supprimer ÉGALEMENT de toute réexportation en cours de route. C'est pourquoi les appels à simplement "exclure ces composants" ci-dessus ont souvent été accueillis avec mécontentement.

En ce qui concerne la limitation restante avec ivy (les erreurs de modèle sur les composants sans modules), est-ce trop demander que ce soient également des avertissements ? Je comprends que cela peut être plus difficile (ou impossible) si la vérification de type se produit avant que le composant ne soit identifié comme sans module, mais il me semble qu'un avertissement du type Warning: ExampleUnusedComponent does not belong to an NgModule, and will be excluded from the output capture avec précision l'idée que le composant (et tous les autres référencés par celui-ci) ne seront pas inclus à moins qu'ils ne soient ajoutés à un ngModule.

Dans l'ensemble, je suis très heureux de voir des progrès sur ce problème et j'ai hâte d'essayer mon cas d'utilisation d'origine avec les nouvelles modifications du compilateur Ivy !

Cette page vous a été utile?
0 / 5 - 0 notes