如果您中有人尝试创建角度库,则他可能会遇到从node_modules延迟加载Feature Module的问题。 让我们更深入地潜入黑暗的水域。

如果您不熟悉问题“如何创建库?” -至少有两个工具可用于创建角度库:
- Angular CLI(引擎盖下的ng-packagr) ;
- 直接ng-packagr ;
您可以通过单击上面的链接来获取更多详细信息,所有其他的操作让我们进一步。
惰性模块(功能模块)

因此,如果您已经使用过Angular,则必须了解Angular模块以及您需要它们的目的。
模块通常必须保留一堆组件,指令服务,这些指令代表某种自给自足的功能。 开发人员通常会为功能创建一个单独的模块,直到用户不会进入特定页面,该功能才需要加载到应用程序中。
现在是Feature Store(暂时不涉及)和Feature模块的时间。
如果将延迟加载的模块包含在某些父模块中,它们就不会延迟,因为您将在应用程序中声明它们,并且在编译时将TypeScript插入JavaScript Webpack中会将这些模块的代码添加到主束中,然后应用程序将加载启动时所有这些代码。
在路由中声明惰性模块的唯一正确方法是。
const routes: Routes = [ { path: 'reports', loadChildren: './reports/reports.module#ReportsModule' } ];
因此,您提供了实际为“#”的特殊字符串,应用程序将知道此模块必须与主应用程序分开加载。
麻烦开始

如果功能模块是应用程序源代码的一部分,那么一切都会很好,但是如果这是使用npm设置的编译库,该怎么办? -它不能以通常的方式工作。
主要问题是,当您尝试通过常规字符串注册此类功能模块时,您将面临错误。
const routes: Routes = [ { path: 'reports',
由于这种声明导致的原因与编译模块不兼容。
您可以制作一个包装,然后在溃败中声明它。
import { ReportsModule } from "my-lib"; @NgModule({ imports: [ReportModule], exports: [ReportModule] }) export class ReportsWrapperModule { } const routes: Routes = [ { path: 'reports', loadChildren: './wrapper.module#ReportsWrapperModule' } ];
但是,谁有兴趣为15个模块创建15个包装? -我不是!
可能的解决方案

我不会隐藏我没有浪费时间分析为什么由于Webpack或某些Angular CLI而发生这种情况。 我发现了两种可能的解决方案。
解决方案#1。 库已编译,并且功能模块没有嵌套的功能模块
该工作示例的链接。
第一步,定义什么类型的LoadChildren属性
type LoadChildren = string | LoadChildrenCallback; type LoadChildrenCallback = () => Type<any> | NgModuleFactory<any> | Promise<Type<any>> | Observable<Type<any>>;
有趣! 因此,从理论上讲,可以使用import()返回带有所需模块的promise。
下一个代码必须没问题。
const routes: Routes = [ { path: 'reports', loadChildren: () => import('my-lib').then((res) => res.ReportsModule) } ];
哦,怎么了? -我们在控制台中看到错误...是的,只需更改tsconfig.json
{ .. "module": "esNext", .. }
现在必须正常工作。
解决方案#2。 Feature Module具有嵌套的Feature模块(仅针对未编译的库完成)
该工作示例的链接。
打包为npm package之前不必编译该库;
由于未编译库的源代码,因此必须将其包含在应用程序的编译过程中。 只需更改tsconfig.app.json ;
"exclude": [ "test.ts", "**/*.spec.ts", "../node_modules/**/*.spec.ts", "../node_modules/**/test.ts" ], "include": [ "*.ts", "./environments", "./app", "../node_modules/my-lib" ]
好消息-无需使用import() ;
const routes: Routes = [{ path: "reports", loadChildren: "my-lib#ReportsModule" }];
塔达姆!
PS这些解决方案仅在Angular 7上进行了测试。
感谢您的关注,享受。