CommonJS 不支持真正的动态加载,require 是同步且静态分析的;可通过条件 require、固定前缀的字符串拼接、预加载映射表等方式模拟,但需注意缓存与打包限制。

CommonJS 规范本身不支持真正的“动态加载”——require 是同步、静态分析的,不能像 ES 模块的 import() 那样在运行时按需加载。但实践中,我们常通过一些模式模拟动态行为,关键在于理解 require 的执行时机和限制。
require 本质是同步加载,不是动态 import
require 在模块加载时(Node.js 启动或 require 被调用时)立即读取文件、执行代码、返回 module.exports。它不接受表达式变量作为路径(如 require(path + '.js')),因为 CommonJS 打包/分析工具(如 Webpack)或 Node.js 的模块解析机制需要在编译期或加载期确定依赖图。直接写 require(someVar) 会导致运行时报错或无法被正确打包。
模拟“动态加载”的常用方式
虽然不能真正动态,但可通过以下方式实现类似效果:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
-
条件 require:把
require写在 if/else 或 switch 中,路径为字面量字符串。Node.js 允许这样写,且所有分支中的模块都会被加载(除非使用 --experimental-strip-exports 等新特性),但逻辑上实现了“按需选择” -
基于字符串拼接的有限动态:只对文件名部分做变量替换,路径前缀固定(如
require('./controllers/' + name + '.js'))。这在 Node.js 中能运行,但会触发所有匹配文件的加载(Webpack 等工具可能警告或打包全部匹配项) -
预加载 + 查找映射表:提前
require一组模块,存入对象或 Map,再根据 key 获取。例如:const plugins = {<br> db: require('./plugins/db'),<br> auth: require('./plugins/auth')<br>};<br>const plugin = plugins[config.type];
注意 Node.js 的 require.cache 和重载问题
多次 require 同一路径不会重复执行模块代码(因缓存),所以“动态切换”模块内容需手动清理缓存:
立即学习“Java免费学习笔记(深入)”;
- 用
delete require.cache[require.resolve('./path.js')]清除缓存 - 之后再次
require才会重新加载并执行模块 - ⚠️ 不推荐在生产环境频繁使用,易引发状态不一致、内存泄漏等问题
真正需要动态加载?考虑替代方案
如果目标是延迟加载、按需拆包或热更新,CommonJS 并非最佳选择:
- Node.js 12+ 支持 ES 模块,可用
import(modulePath)实现真正的异步动态导入 - 构建工具如 Webpack 提供
require.ensure(旧)或import()(推荐)做代码分割 - 对于插件系统,更健壮的做法是约定目录结构 +
fs.readdirSync+require动态遍历(仍属预加载,但路径可控)

















