Si quelqu'un d'entre vous a essayé de créer des bibliothèques angulaires, il peut être confronté au problème de chargement paresseux du module de fonctionnalité à partir de node_modules . Plongeons plus profondément et traversons l'eau sombre.

Si vous n'êtes pas familier avec la question "Comment créer la bibliothèque?" - Il existe au moins deux outils pour créer une bibliothèque angulaire:
- CLI angulaire (ng-packagr sous le capot) ;
- Directement le ng-packagr ;
Vous pouvez obtenir plus de détails en cliquant sur les liens ci-dessus, tous les autres allons plus loin.
Modules paresseux (modules fonctionnels)

Donc, si vous avez déjà travaillé avec Angular, vous devez connaître les modules Angular et à quelles fins vous en avez besoin.
Un module doit généralement conserver un ensemble de composants, des services de directives qui représentent une certaine fonctionnalité autosuffisante. Souvent, le développeur crée un module distinct pour une fonctionnalité qui ne doit pas être chargée dans l'application jusqu'à ce qu'un utilisateur n'aille pas sur une page particulière.
Et maintenant, il est temps pour Feature Store (pas à ce sujet pour l'instant) et module de fonctionnalités.
Si vous incluez des modules Lazy Loaded dans un module parent, ils ne seront pas paresseux, car vous les déclarerez dans l'application et au moment de la compilation TypeScript dans le JavaScript Webpack ajoutera le code de ces modules dans le groupe principal et l'application se chargera tout ce code au démarrage.
Une seule façon correcte de déclarer un module paresseux dans le routage.
const routes: Routes = [ { path: 'reports', loadChildren: './reports/reports.module#ReportsModule' } ];
Vous fournissez donc la chaîne spéciale qui en fait "#" et l'application saura que ce module doit être chargé séparément de l'application principale.
Les ennuis commencent

Tout va bien si le module de fonctionnalités fait partie du code source de votre application, mais que se passe-t-il s'il s'agit d'une bibliothèque compilée configurée à l'aide du npm? - Cela ne fonctionne pas de manière habituelle.
Le principal problème est que lorsque vous essayez d'enregistrer un tel module de fonction par chaîne habituelle, vous serez confronté à l'erreur.
const routes: Routes = [ { path: 'reports',
Il provoque en raison de ce type de déclaration ne sont pas compatibles pour les modules compilés.
Vous pouvez créer un wrapper, puis le déclarer dans les routs.
import { ReportsModule } from "my-lib"; @NgModule({ imports: [ReportModule], exports: [ReportModule] }) export class ReportsWrapperModule { } const routes: Routes = [ { path: 'reports', loadChildren: './wrapper.module#ReportsWrapperModule' } ];
MAIS, qui souhaite créer 15 wrappers pour 15 modules? - Je ne le suis pas!
Solutions possibles

Je ne cacherai pas que je n'ai pas perdu de temps à analyser pourquoi cela se produit en raison de Webpack ou d'une CLI angulaire. J'ai trouvé deux solutions possibles.
Solution n ° 1. Bibliothèque compilée et module de fonctionnalités ne comportant aucun module de fonctionnalités imbriqué
Lien pour l'exemple de travail.
Première étape définir quel type d'attribut LoadChildren
type LoadChildren = string | LoadChildrenCallback; type LoadChildrenCallback = () => Type<any> | NgModuleFactory<any> | Promise<Type<any>> | Observable<Type<any>>;
Intéressant! Donc, théoriquement, il est possible d'utiliser import () pour renvoyer promesse avec le module requis.
Le code suivant doit être correct.
const routes: Routes = [ { path: 'reports', loadChildren: () => import('my-lib').then((res) => res.ReportsModule) } ];
Oh, que se passe-t-il? - Nous voyons des erreurs dans la console ... Oui, changez simplement tsconfig.json
{ .. "module": "esNext", .. }
Maintenant, cela doit bien fonctionner.
Solution n ° 2. Le module d'entités a des modules d'entités imbriqués (fait uniquement pour une bibliothèque non compilée)
Lien pour l'exemple de travail.
Vous ne devez pas compiler la bibliothèque avant d'empaqueter vers le paquet npm;
Comme la source de la bibliothèque n'est pas compilée, vous devez l'inclure dans le processus de compilation de votre application. Modifiez simplement tsconfig.app.json ;
"exclude": [ "test.ts", "**/*.spec.ts", "../node_modules/**/*.spec.ts", "../node_modules/**/test.ts" ], "include": [ "*.ts", "./environments", "./app", "../node_modules/my-lib" ]
Bonne nouvelle - pas besoin d'utiliser import () ;
const routes: Routes = [{ path: "reports", loadChildren: "my-lib#ReportsModule" }];
Tadam!
PS Ces solutions sont testées avec Angular 7 uniquement.
Merci de votre attention, profitez-en.