一、优先从缓存中加载
// main.js
require('/a')
let b = require('/b')
console.log(b)
//输出
// a.js被加载
// b.js被加载
// function
// function
// a.js
console.log('a.js被加载')
let b = require('/b')
console.log(b)
// b.js
console.log('b.js被加载')
module.exports = function(){
console.log('hello i am b')
}
优先从缓存中加载,当加载一个模块的时候先判断该模块是否被加载过,如果已经加载过了,则直接从缓存中拿到接口对象,则不会再重复加载(重复执行其中的代码)。
在上例中,a.js中已经加载过b.js,在main.js中执行到require('/b')时,从缓存中发现已经加载过了,所以不会重复加载b.js(b.js中的代码只执行了一次),并且可以从缓存中拿到接口对象(b.js中的module.exports)
这样做的目的是为了避免重复加载,提高模块加载效率
二、判断模块标识符
1.核心模块
本质也是文件,核心文件已经被编译到二进制文件中了,我们只需要按照名字来加载就可以了
requirs('fs')
require('http')
2.第三方模块
- 第三方模块都需要通过npm 下载
- 使用的时候通过 require('包名') 的方式进行加载才可以使用
- 不可能有任何一个第三方包的名字和核心模块的名字一样
- 加载第三方模块的过程:先找到当前文件所处目录中的node_module 目录
- node_module/are-template/package.json 中的 main 属性记录了art-template模块的入口文件,即加载art-template模块的时候实际上加载的该文件
- 若没有package.json文件,或者main中的信息为空或者是错误的,node会自动读取 node_module/are-template 目录下的 index.js 文件
- 如果以上所有条件都不成立,则会进入上一级目录中的node_mudule 目录查找,如果上一级还没有,则进入上上一级查找。。。直到当前磁盘根目录还找不到,最后报错:can not find module xxx
- 通常:项目中有且只有一个node_module,放在项目根目录,这样项目所有子目录中的代码都可以加载到第三方包
3.自己写的模块
路径形式的模块:
./ 当前目录
../ 上一级目录
../../ 上上一级目录
/xxx 当前文件模块所属磁盘根路径
d:/a/foo.js 绝对路径