模块查找
- 绝对 路径 D:\ (无论什么路径 最终都会转为绝对路径)
- 相对路径 ./(本菜单) ../(上级菜单)
- 相对路径 require("aaa")
- 检查是否为内置模块"fs" "path"
- 检查当前目录的node_modules
- 检查上级目录的node_modules
- 转为绝对路径
- 加载模块
- 后缀 如果不提供后缀名,会补全 js,json,node,msj
- 文件名 如果提供目录,不提供文件名,自动寻找该目录的 index.js(或者 目录下有package.json 读取main字段,没有默认 index.js)
module 对象
-
记录当前模块信息
Module {
id: '.', // 入口模块 为 . 模块路径 或者 绝对路径
path: 'D:\\学习\\nodeSelf', // 模块目录(使用模块)
exports: {},
parent: null, // 入口模块 没有父模块
filename: 'D:\\学习\\nodeSelf\\index.js', // 文件目录(使用文件)
loaded: false, // 是否加载完 一般后面都有导入 都为false
children: [], // [Circular] 递归 是自己
paths: [ // 更具这个路径查找 文件
'D:\\学习\\nodeSelf\\node_modules',
'D:\\学习\\node_modules',
'D:\\node_modules'
]
}
require 函数
[Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] }, // 解析路径,返回绝对路径 偶尔会用
main: Module { // 入口模块 数据 和 module 一样
id: '.',
path: 'D:\\学习\\nodeSelf',
exports: {},
parent: null,
filename: 'D:\\学习\\nodeSelf\\index.js',
loaded: false,
children: [],
paths: [
'D:\\学习\\nodeSelf\\node_modules',
'D:\\学习\\node_modules',
'D:\\node_modules'
]
},
extensions: [Object: null prototype] { // 拓展名 的处理函数 还有个 .mjs
'.js': [Function (anonymous)],
'.json': [Function (anonymous)],
'.node': [Function (anonymous)]
},
cache: [Object: null prototype] { // 缓存 如果有的话 会直接加载,没有去文件找
'D:\\学习\\nodeSelf\\index.js': Module {
id: '.',
path: 'D:\\学习\\nodeSelf',
exports: {},
parent: null,
filename: 'D:\\学习\\nodeSelf\\index.js',
loaded: false,
children: [],
paths: [Array]
}
}
}
require 伪代码
function require() {
// 1. 判断什么路径书写方式,转为绝对路径,找不到绝对路径报错
// 2. 判断是否该模块已有缓存 读取 require.cache 如果有 则直接返回
// 3. 读取文件内容
// 4.包裹在一个函数中
function __temp( module, exports, require,__dirname,__filename ){}
//创建 module对象
module.exports = {};
const exports = module.exports;
__temp.call(module.exports,module, exports, require,__dirname,__filename)
return module.exports 最终返回 module.exports
}
所以在文件中
this 和 exports 和 module.exports 基本一致 ;只要为改变 三者的引用
exports.c = 3
this.m = 3
module.exports.a = 1
// 返回 { a: 1,m: 3,c: 3 }
module.exports = { a: 1 }
exports.c = 3
this.m = 3
// 返回 { a: 1 }
// 最终的结果 返回module.exports 和代码顺序无关,主要是因为 require 最终返回 module.exports