node.js模块加载遵循扩展名自动补全、目录入口查找、路径类型区分及缓存机制。依次尝试.js/.json/.node;目录下按package.json main、index.js/index.json/index.node查找;相对路径从当前文件目录查,绝对路径直接定位,纯名称先内置后向上搜node_modules;已加载模块缓存于require.cache,后续调用直接返回缓存结果。

当使用 require() 加载模块并省略扩展名时,Node.js 会按固定顺序尝试添加后缀查找文件,这个过程叫“扩展名自动补全”,它有明确的优先级规则。
默认尝试的扩展名顺序
Node.js 会依次尝试以下扩展名(按顺序):
-
.js(最高优先级) .json-
.node(用于 C++ 插件)
例如:require('./utils') 会依次查找:./utils.js → ./utils.json → ./utils.node,找到第一个存在的即停止。
目录模块的加载逻辑
如果 require() 的路径指向一个目录(如 require('./lib')),Node.js 按如下顺序查找入口文件:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 先读取该目录下的
package.json,取main字段指定的文件(如"main": "index.cjs") - 若无
package.json或main不合法,则尝试加载index.js - 若
index.js不存在,再试index.json,最后是index.node
路径类型影响查找起点
不同形式的路径触发不同查找策略:
-
相对路径(如
./foo):从当前require所在文件的目录开始查找 -
绝对路径(如
/home/user/foo):直接定位,不依赖上下文目录 -
纯名称(如
fs或lodash):优先匹配内置模块;若不是,则从当前文件所在位置向上逐级搜索node_modules目录
缓存与重复加载
模块一旦成功加载,就会被缓存在 require.cache 中。后续相同路径的 require() 调用直接返回缓存结果,不再重新解析或尝试扩展名。
这意味着即使你后来新增了 utils.json,只要之前已加载过 utils.js,再次 require('./utils') 仍返回原来的 .js 模块。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










