You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 9:无需箭头函数,如何基于JSON配置懒加载模块?

解决Angular 9+从JSON动态构建懒加载路由的模块找不到问题

我之前也踩过这个坑,核心原因是Angular 9+的懒加载依赖ES动态import(),而webpack需要静态解析import()的路径参数——你直接从JSON里拿字符串当import的参数,webpack在构建时根本没法识别这是要打包的模块路径,自然会报"Cannot find module"的错。

下面给你几个可行的解决方案,从手动维护到自动扫描都有:


方案1:手动维护模块加载映射表

这个方案最直接,适合插件数量不多的场景:

  1. 新建一个plugin-loader.ts文件,把所有插件模块的加载函数提前定义好(webpack能静态分析到这些import,会把模块打包进去):
// plugin-loader.ts
export const pluginLoaders = {
  './plugins/gallery/gallery.module': () => import('./plugins/gallery/gallery.module'),
  './plugins/chats/chats.module': () => import('./plugins/chats/chats.module')
};
  1. 修改主模块里的路由构建代码,从映射表中获取对应的加载函数,而不是直接用JSON的字符串:
// 主模块代码
import { Route } from '@angular/router';
import pluginsList from './plugins/plugins.json';
import { pluginLoaders } from './plugin-loader';

const pluginsModules: Route[] = [];

pluginsList.forEach(item => {
  // 从映射表拿到对应的加载函数
  const loadModule = pluginLoaders[item.loadChildren];
  if (loadModule) {
    pluginsModules.push({
      path: item.path,
      // 加载模块后,取导出的NgModule类(这里假设每个模块的类名和文件名对应,比如GalleryModule)
      loadChildren: () => loadModule().then(m => m.GalleryModule)
    });
  }
});

export const pluginsRoutes = pluginsModules;

如果每个插件的模块类名不一样,可以在plugins.json里加个moduleName字段,比如:

// plugins.json
[
  { "path": "gallery", "loadChildren": "./plugins/gallery/gallery.module", "moduleName": "GalleryModule" },
  { "path": "chats", "loadChildren": "./plugins/chats/chats.module", "moduleName": "ChatsModule" }
]

然后修改路由构建的代码:

loadChildren: () => loadModule().then(m => m[item.moduleName])

方案2:用webpack的require.context自动扫描插件模块

如果插件数量多,不想手动维护映射表,可以用webpack的require.context自动扫描plugins目录下的所有模块:

  1. 新建plugin-loader.ts,利用require.context创建模块上下文:
// plugin-loader.ts
// 扫描plugins目录下所有.ts结尾的模块文件,递归子目录
const pluginContext = require.context('./plugins', true, /\.module\.ts$/);

export const pluginLoaders: Record<string, () => Promise<any>> = {};

// 遍历所有扫描到的模块,构建路径到加载函数的映射
pluginContext.keys().forEach(key => {
  // 把webpack返回的key格式(比如'./gallery/gallery.module.ts')转换成和JSON里匹配的路径
  const targetPath = `./plugins${key.slice(1).replace('.ts', '')}`;
  pluginLoaders[targetPath] = () => pluginContext(key);
});
  1. 主模块的路由构建代码和方案1一样,直接用这个自动生成的映射表就行——这样新增插件时,只要放在plugins目录下,JSON里配置好路径,就能自动被识别,不用修改映射表。

关键注意点

  • 确保每个插件模块都正确导出了NgModule类,比如GalleryModule要通过export class GalleryModule {}暴露出来;
  • 插件模块里要配置RouterModule.forChild([...]),不然懒加载的路由不会生效;
  • 如果你用的是Angular 10+,可以考虑用loadChildren: () => import('./path').then(m => m.ModuleName)的简写,但核心还是要让webpack能静态分析到import的路径。

内容的提问来源于stack exchange,提问作者Atif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:28:12