前言
准备整理node 系列,先把一些基础含义放出来。
在学习node 的时候我们一般加载模块都是require,那么require 是如何运行的呢?
正文
通常,在Node.js里导入是通过 require函数调用进行的。 Node.js会根据 require的是相对路径还是非相对路径做出不同的行为。
绝对路径没什么可说,那么看下相对路径吧。
例如,假设有一个文件路径为 /root/src/moduleA.js,
包含了一个导入var x = require("./moduleB"); Node.js以下面的顺序解析这个导入:
检查/root/src/moduleB.js文件是否存在。
检查/root/src/moduleB目录是否包含一个package.json文件,且package.json文件指定了一个"main"模块。
在我们的例子里,如果Node.js发现文件 /root/src/moduleB/package.json包含了{ "main": "lib/mainModule.js" },
那么Node.js会引用/root/src/moduleB/lib/mainModule.js,这个也就是我们告诉require的加载路径。
如果没有的话,那么会检查/root/src/moduleB目录是否包含一个index.js文件。 这个文件会被隐式地当作那个文件夹下的"main"模块。
然后顺便扩展一下require:
require 引用是同步的,没有异步这么一说。
setouttime(function(){
export=a;
})
如果我们require的时候,那么这个时候是请求到{}的,也就是没有暴露任何的元素.
require 循环引用这里是一个重点了。
require 循环引用,很有可能是个坑。
直接看官方例子:
a.js:
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
b.js:
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
main.js:
console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done = %j, b.done = %j', a.done, b.done);
执行得到的结果如下:
$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done = true, b.done = true
其实很简单,当请求a的时候,a按照顺序执行。
然后a中请求b的时候,会阻塞a,执行b,当b执行完后才开始执行a。