web-dev-qa-db-fra.com

Angular 6/7 "le résultat d'une dépendance est une expression"

J'essaie de créer une bibliothèque Angular 6 et de l'utiliser dans une application Angular 6. Je l'ai réduit à un cas de test minimal. (Mise à jour: puisque Angular 7 est sorti, j'ai aussi essayé.)

ng new workspace # accept the defaults
ng new product # accept the defaults
cd workspace 
ng generate library widgets 
ng build --prod widgets # leave out "--prod" for Angular 7
cd ../product
ng build

Une application appelée "espace de travail" héberge une bibliothèque appelée "widgets". Une autre application appelée "produit" est seule. Tout va bien à ce stade.

Essayons maintenant d'utiliser la bibliothèque "widgets" dans l'application "product". Ouvrez le fichier product/src/app/app.module.ts qui a été généré par la CLI. Ajoutez deux lignes comme indiqué ci-dessous.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { WidgetsModule } from '../../../workspace/dist/widgets'; //  added

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    WidgetsModule // added
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Après ce changement, lorsque je lance ng build à partir du répertoire du produit, Webpack m'avertit.

Date: 2018-07-31T13:13:08.001Z
Hash: 8a6f58d2ae959edb3cc8
Time: 8879ms
chunk {main} main.js, main.js.map (main) 15.9 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 227 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 5.22 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 15.6 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 4.59 MB [initial] [rendered]

WARNING in ../workspace/node_modules/@angular/core/fesm5/core.js
4997:15-36 Critical dependency: the request of a dependency is an expression

WARNING in ../workspace/node_modules/@angular/core/fesm5/core.js
5009:15-102 Critical dependency: the request of a dependency is an expression

Que signifie "le résultat d'une dépendance est une expression"? Qu'est-ce que je fais mal?

43
Patrick McElhaney

Le problème principal n’est pas de savoir pourquoi vous recevez ces avertissements. La façon dont vous accédez à la bibliothèque n’est pas idéale. Examinons une approche un peu meilleure [Utilisation de Angular 7] avec vos propres exemples d'étapes, ce qui ne posera pas ce problème à l'origine.


Étape 1: [identique à la vôtre]

ng new workspace # accept the defaults
ng new product # accept the defaults
cd workspace 
ng generate library widgets 
ng build --prod widgets # leave out "--prod" for Angular 7
cd ../product
ng build

Étape 2: Créer le fichier de bibliothèque .tgz

cd ../workspace/dist/widgets/
npm pack
cp widgets-0.0.1.tgz ../../../product/

Étape 3: Ajouter la bibliothèque "widgets" dans package.json

Ouvrez le fichier package.json du projet product et, sous devDependencies, ajoutez la ligne suivante:

"widgets": "file:./widgets-0.0.1.tgz",

Les étapes 2 et 3 sont obligatoires si vous avez la bibliothèque localement. Sinon, si votre bibliothèque est compressée et publiée dans le référentiel npm, vous n'avez pas besoin du mot clé file:. Vous pouvez simplement mentionner la version comme d'autres dépendances.


Étape 4: Installer la bibliothèque nouvellement ajoutée

Exécutez npm install dans le projet de produit.


Étape 5: Utilisez la bibliothèque

Modifier le fichier app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { WidgetsModule } from 'widgets'; // new line

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    WidgetsModule // new line
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Étape 6: Construire le projet de produit

Maintenant, exécutez ng build dans le projet de produit. Il fonctionnera avec succès.

Angular Product Project Build

19
Saddam Pojee

Cette erreur survient lorsqu'une dépendance JS est exprimée à l'aide d'une expression plutôt que d'une chaîne fixe - par exemple, require('horse' + variable) ou require(function() { return 'horse'+variable }). Il est probable que votre WidgetsModule importe quelque chose en train d'importer une bibliothèque remplissant cette forme de besoin.

Webpack s'en plaint car cela signifie qu'il doit inclure tous les fichiers d'un dossier plutôt que de pouvoir analyser de manière statique les fichiers à inclure. Cela fonctionnera toujours, mais selon la discussion sur ce problème de Webpack , il ne devrait pas être ignoré et la dépendance en question devrait être refactorisée.

J'ai récemment rencontré cette erreur lors de la mise à niveau récente d'un projet Angular de v5 à v6, et si je me souviens bien, cette erreur a disparu une fois que j'ai mis à niveau toutes les autres dépendances vers leurs dernières versions - Cependant, je ne peux pas dire quelle dépendance était à l'origine du problème, et malheureusement, je n'ai pas commis d'erreur entre voir l'erreur et la corriger, je ne peux donc pas analyser le changement exact corrigeant l'erreur.

Il semble cependant que beaucoup de gens ont des problèmes similaires - voir par exemple https://github.com/angular/angular/issues/20357

Pour effacer l'avertissement (sans résoudre le problème sous-jacent), vous devez suivre cette procédure , en ajoutant:

plugins: [
    // Workaround for Critical dependency 
    // The request of a dependency is an expression in ./node_modules/@angular/core/fesm5/core.js
    new webpack.ContextReplacementPlugin(
        /\@angular(\\|\/)core(\\|\/)fesm5/,
        helpers.root('./src'),
        {}
    )
]

... à la configuration du webpack. Cependant, dans la dernière Angular CLI, vous ne pouvez pas modifier manuellement la configuration du Webpack (l'ancienne commande ng eject qui autorisait cette opération a été supprimée). Par conséquent, je ne pense pas que vous puissiez corriger le problème. avertissement à ce moment.

Ceci conclut que les auteurs de la CLI Angular doivent masquer cette erreur via la configuration générée du pack Web qu'il utilise en interne, ou que les auteurs de Angular changent la core.js fait ses importations.

18
Mark Hughes

J'ai rencontré le même avertissement concernant "le résultat d'une dépendance est une expression" faisant référence à fesm5.js dans un nouveau projet généré par Angular 7 cli.

Ce projet particulier fait référence à un package npm local avec un chemin relatif commençant par file://../ qui semblait provoquer l'avertissement.

Après quelques recherches, j’ai trouvé ce problème de Github qui explique comment résoudre ce problème dans Angular 6+ applications générées par cli.

Ce qui a fonctionné pour moi a été d'ouvrir le fichier angular.json dans le dossier racine du projet client (pas celui de la bibliothèque partagée) et de trouver ce chemin:

projects > (your project name) > architect > build > options

et ajoutez la clé:

"preserveSymlinks": true

avec tout le reste du fichier omis voici les parties pertinentes:

{
  "projects": {
    "MyAwesomeProject": {
      "architect": {
        "build": {
          "options": {
            "preserveSymlinks": true
          }
        }
      }
    }
  }
}

Après avoir ajouté ceci, je reçois ng build normal sans avertissements. J'espère que ça t'as aidé!

17
H Dog

C'est la BrowserModule qui provoque cet avertissement. Je ne connais pas la raison, mais il semble que ce soit la source de l'avertissement.

5
Amr ElAdawy