require
都是模块化编程的诞生物,是 AMD
规范引入方式,提供了服务器/浏览器的模块加载方案。只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。require
加载模块可分为下面三种情况:
-
加载核心模块
核心模块默认已经被封装编译到二进制文件中了,直接使用加载就行;
例如
require('fs')
、require('http')
-
加载本地模块(自己写的模块)
必须以路径的形式加载,否则
node
会把他当成是核心模块或者第三方模块加载,文件后缀.js
可以忽略。例如:
require('./a.js')
、require('../b.js')
-
加载第三方模块(通过
npm
下载安装的模块)为什么第三方模块不会和核心模块加载冲突?
因为不可能有第三方模块名会和核心模块名一样(规定)
模块加载原理?
-
当
require('模块名')
后,例如require('esprima')
-
先找到当前文件目录所在的
node_module
文件夹 -
找到
node_module
文件夹中对应加载模块名的文件夹,例如node_modules/esprima
-
找到
node_modules/esprima/package.json
文件 -
node_modules/esprima/package.json
文件的main
属性(main
属性记录了esprima
的入口模块) -
加载使用这个第三方包(即最终加载的还是
js
文件) -
如果
package.json
文件不存在或者main
指定的入口模块是也没有则node
会自动找目录下的index.js
也就是说index.js
会作为一个默认备选项 -
如果以上所有,任何一个条件都不成立,则会进入上一级目录中的
node_module
目录查找 -
如果上一级还没有,则继续往上一级 直到当前磁盘根目录还找不到,最后报错
-
参考:
https://blog.csdn.net/cangqiong_xiamen/article/details/102832604
https://www.freesion.com/article/27031156344/