1.暴露数据
模块暴露数据的两种方式:
- module.exports = value
- exports = value
– 模块内部module与exports的隐式关系exports = module.exports = {}
2.导入(引入)模块
require使用的一些注意事项
-
对于自己创建的模块,导入时路径建议写
相对路径
,且不能省略./
和../
-
js
和json
文件导入时可以不用写后缀,遇到js和json同名的文件,优先导入js文件 -
如果导入其他类型的文件,会以
js
文件进行处理 -
如果导入的路径是个文件夹,则会首先检测该文件夹下
package.json
文件中的main
属性对应的文件,如果main属性不存在,或者package.json不存在,则会检测文件夹下的index.js
和index.json
,如果还没找到,则会报错。
-
导入node.js内置模块时,直接require模块名字即可,无需加
./
和../
– module.exports
、exports
以及require
这些都是CommonJS
模块化规范中的内容,而Node.js实现了CommonJS模块化规范
3.require基本流程
- 将相对路径转为绝对路径,定位目标文件
- 缓存检测
- 读取目标文件
- 包裹为一个函数并自执行(自执行函数),通过
arguments.callee.toString()
查看自执行函数 - 缓存模块的值
- 返回
module.exports
的值
/*
以下为require执行过程的伪代码
*/
const fs = require('fs')
function require(file){
// 将相对路径转为绝对路径
let absolutePath = path.resolve(__dirname,file)
// 缓存检测
if(caches[absolutePath]){
return caches[absolutePath]
}
// 读取文件的代码
let code = fs.readFileSync(absolutePath).toString()
// 包裹为一个函数,然后执行
let module = {}
let exports = module.exports = {}
(function (exports,require,module,__filename,__dirname){
const test = {
age:25
}
module.exports = test
// 输出
console.log(arguments.callee.toString());
})(exports,require,module,__filename,__dirname)
// 缓存结果
caches[absolutePath] = module.exports
}