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?
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.
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
cd ../workspace/dist/widgets/
npm pack
cp widgets-0.0.1.tgz ../../../product/
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.
Exécutez npm install
dans le projet de produit.
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 { }
Maintenant, exécutez ng build
dans le projet de produit. Il fonctionnera avec succès.
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.
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é!
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.