1. 模块
- node自带模块化功能,一个js文件就是一个模块(即每个文件被视为独立的模块)
- 下面是模块的一个简单应用
- 假设有一个Dialog的文件
// Dialog.js
function Dialog(){
this.time = 3000;
}
Dialog.prototype.$show = function(){
console.log('show');
};
Dialog.prototype.$hide = function(){
console.log('hide');
};
exports.dialog = Dialog;
- 这里有一个UseDialog的文件,来使用Dialog这个模块
// UseDialog.js
var dialog = require('./a');
var dialog1 = new dialog.dialog;
console.log(dialog1.time); // 输出为3000
dialog1.$hide(); // 执行$hide()函数
dialog1.$show(); // 执行$show()函数
2.关于模块中的变量与this
- 模块内的变量是私有变量,是由于模块被包含在一个函数中(详见下面的模块包装器);
- 如果我们需要将一个变量设置为全局的变量,我们可以在定义变量时不用var,即直接定义;或者将这个变量挂载到全局变量上,即global,如下所示:
global.aaa = 1;
bbb = 2;
console.log(global.aaa); // 打印出为1
console.log(global.bbb); // 打印出为2
- 在js中,我们知道,自执行函数中,this的指向是window,在模块中this为空对象
console.log(this); // 打印出为 {}
3.模块的引入
- 首先会先查找node自带的模块
- 查找第三方模块,及我们自己安装的模块,会安装在node_modules目录下
- 在引入自己的模块的时候,必须是相对路径,否则会发生报错:Cannot find module 'a'
- 在加载一个模块时,可以进行多次引入,但在执行模块代码时只执行一次,且对已经引入的模块会产生缓存
- a.js
console.log('start load;')
exports.fn = function(){
console.log('aaa');
};
console.log('end load;')
- b.js
var a = require('./a');
var b = require('./a');
console.log(a===b);
- 运行b.js结果为
start load;
end load;
true
4.模块包装器
- 在执行模块代码之前,Node.js 会使用一个如下的函数包装器将其包装
(function(exports, require, module, __filename, __dirname) {
module.exports = exports = this = {};
// 模块中自己写的代码
return module.exports;
});
- 从上面的代码可以看出exports与module.exports的区别,在node底层代码是module.exports = exports,但由于真正的导出的是module.exports,故我们在进行模块导出时,不可进行如下写法,这是由于我们将exports重新指向了一个新的对象,这样module.exports的指向还是{},也就导致了在其它模块引入该模块时,得到的是一个空对象{}
exports = {name:'Anna'};
5.目录模块的加载
- 可以把程序和库放到一个单独的目录,然后提供一个单一的入口来指向它
1)根目录下创建一个 package.json
文件,并指定一个 main
模块,package.json
文件如下:
如果此时目录为som-library,则require('./some-library'),就是对./some-library/lib/some-liabary.js进行加载
{ "name" : "some-library",
"main" : "./lib/some-library.js" }
- 如果在package.json中main指定的入口文件不存在,那么就会抛出错误
2)如果目录中没有package.json文件,则会默认加载当前目录下的index.js/index.done文件,则require('./some-library'),就会试图加载
./some-library/index.js
./some-library/index.node
3)如果传递给 require()
的模块标识符不是一个核心模块,也没有以 '/'
、 '../'
或 './'
开头,则 Node.js 会从当前模块的父目录开始,尝试从它的 /node_modules
目录里加载模块。找对应目录中package.json中main对应的文件运行,如果当前目录下没找到会向上一级查找,直至找到或达到根目录位置
文章参考:nodejs官网模块