Angular 13+无需废弃编译器的无路由模块懒加载实现方案咨询
Angular 13+ 无路由场景下懒加载NgModule的实现方案
Angular 13 全面切换为Ivy编译模式后,废弃了原有基于Compiler手动编译模块的API,无需在运行时手动处理模块、组件的编译逻辑,整套流程大幅简化,具体实现步骤如下:
核心实现步骤
- 第一步:通过
import()语法动态导入目标NgModule类,不需要再调用编译器的异步编译方法 - 第二步:调用
createNgModule方法直接创建模块实例,传入全局注入器即可完成模块初始化 - 第三步:从模块实例中获取需要渲染的组件类(建议懒加载模块主动暴露获取组件的公共方法,也可以提前约定模块导出的组件类名)
- 第四步:调用
ViewContainerRef.createComponent直接传入组件类完成渲染,不需要提前创建组件工厂
完整代码示例
首先在使用的组件/服务中注入依赖:
import { createNgModule, Inject, Injectable, Injector, ViewContainerRef } from '@angular/core'; // 你自己的业务模块类型定义(可选,用于类型提示) import type { LazyModule } from './lazy/lazy.module'; @Injectable() export class LazyLoaderService { constructor( private injector: Injector, private viewContainerRef: ViewContainerRef ) {} async loadLazyModule() { // 1. 动态导入模块 const { LazyModule } = await import('./lazy/lazy.module'); // 2. 初始化模块实例 const lazyModuleRef = createNgModule<LazyModule>(LazyModule, this.injector); // 3. 从模块实例获取目标组件类,示例中LazyModule暴露了getEntryComponent方法返回要渲染的组件 const targetComponent = lazyModuleRef.instance.getEntryComponent(); // 4. 直接渲染组件,传入模块注入器可以让组件正常使用模块内声明的providers const componentRef = this.viewContainerRef.createComponent(targetComponent, { injector: lazyModuleRef.injector }); // 后续可正常操作componentRef的实例,传参、绑定事件等 } }
配套懒加载模块写法示例
在你的懒加载模块中,主动暴露获取入口组件的方法即可:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LazyEntryComponent } from './lazy-entry/lazy-entry.component'; @NgModule({ declarations: [LazyEntryComponent], imports: [CommonModule] }) export class LazyModule { // 暴露方法返回要渲染的入口组件 getEntryComponent() { return LazyEntryComponent; } // 如果需要按选择器匹配组件,可以维护映射表 getComponentBySelector(selector: string) { const selectorMap = { 'app-lazy-entry': LazyEntryComponent }; return selectorMap[selector]; } }
注意事项
- 不需要再引入
Compiler服务相关的代码,Ivy模式下所有模块和组件的编译信息会在构建阶段提前生成,运行时无需二次编译 - 给
createComponent传入懒加载模块的注入器,组件就能正常使用模块内部声明的providers、导入的其他模块提供的依赖,作用域逻辑和旧版本完全一致 - 若需要销毁懒加载模块,手动调用
lazyModuleRef.destroy()即可,会同时清理模块内的作用域资源
内容的提问来源于stack exchange,提问作者Ben Racicot
相关产品推荐
相关产品推荐

