CommonJS浅析

栏目: Node.js · 发布时间: 4年前

内容简介:规范地址nodejs modules文档地址在执行模块代码之前,nodejs会使用一个闭包(The module wrapper)封装起来,这就是它每一个文件都是一个独立的域的原因。但如果值没有用var声明的变量,会直接提升到全局上去,在其他文件也可以直接使用。

规范地址 http://www.commonjs.org/

nodejs modules文档地址 http://nodejs.cn/api/modules....

核心逻辑

在执行模块代码之前,nodejs会使用一个闭包(The module wrapper)封装起来,这就是它每一个文件都是一个独立的域的原因。但如果值没有用var声明的变量,会直接提升到全局上去,在其他文件也可以直接使用。

nodejs会通过下面一个闭包把文件给包起来

(function(exports, require, module, __filename, __dirname) {
// 模块的代码实际上在这里
});

我们可以使用

console.log(JSON.stringify(arguments))
可以看到当前js文件封装之后的参数
例:
aa.js
console.log(JSON.stringify(arguments))
//  {"0":{},"2":{"id":".","exports":{},"parent":null,"filename":"D:\\code\\js\\aa.js","loaded":false,"children":[],"paths":["D:\\code\\js\\node_modules","D:\\code\\node_modules","D:\\node_modules"]},"3":"D:\\code\\js\\aa.js","4":"D:\\code\\js"}‘

可以看到这里返回的对象对应着exports, require, module, __filename, __dirname

exports

在整个域里,会有两个exports,一个模块封装器里的首个参数,一个是module类里的。

两个exports引用了同一块堆内存,require引用时实际上拿的是module类里的

require

用于引入模块、 JSON、或本地文件。 可以从 node_modules 引入模块。 可以使用相对路径(例如 ./、 ./foo、 ./bar/baz、 ../foo)引入本地模块或 JSON 文件,路径会根据 __dirname 定义的目录名或当前工作目录进行处理。

上面是官网对require的定义,require的一些属性使用在官网也有定义

module

在每个模块中, module 的自由变量是对表示当前模块的对象的引用。 为方便起见,还可以通过全局模块的 exports 访问 module.exports。 module 实际上不是全局的,而是每个模块本地的。

__filename

当前模块的文件名。 这是当前的模块文件的绝对路径(符号链接会被解析)。

__dirname

当前模块的目录名。 与 __filename 的 path.dirname() 相同。

特殊使用

循环引用

当循环调用 require() 时,一个模块可能在未完成执行时被返回。

例如以下情况:

a.js:

console.log('a 开始');
exports.done = false;
const b = require('./b.js');
console.log('在 a 中,b.done = %j', b.done);
exports.done = true;
console.log('a 结束');
b.js:

console.log('b 开始');
exports.done = false;
const a = require('./a.js');
console.log('在 b 中,a.done = %j', a.done);
exports.done = true;
console.log('b 结束');
main.js:

console.log('main 开始');
const a = require('./a.js');
const b = require('./b.js');
console.log('在 main 中,a.done=%j,b.done=%j', a.done, b.done);

当 main.js 加载 a.js 时, a.js 又加载 b.js。 此时, b.js 会尝试去加载 a.js。 为了防止无限的循环,会返回一个 a.js 的 exports 对象的 未完成的副本 给 b.js 模块。 然后 b.js 完成加载,并将 exports 对象提供给 a.js 模块。

当 main.js 加载这两个模块时,它们都已经完成加载。 因此,该程序的输出会是:

$ node main.js
main 开始
a 开始
b 开始
在 b 中,a.done = false
b 结束
在 a 中,b.done = true
a 结束
在 main 中,a.done=true,b.done=true

以上所述就是小编给大家介绍的《CommonJS浅析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Docker——容器与容器云

Docker——容器与容器云

浙江大学SEL实验室 / 人民邮电出版社 / 2015-9-1 / 89.00元

本书从实践者的角度,在讲解Docker高级实践技巧的同时,深入到源代码层次,为读者梳理出Docker容器技术和基于Docker的容器云技术(如Kubernetes)的实现方法和设计思路,帮助读者理解如何在实际场景中利用Docker解决问题并启发新的思考。全书包括两部分,第一部分深入解读Docker容器技术,包括Docker入门、架构总览、Docker容器核心原理解读,以及Docker高级实践技巧;......一起来看看 《Docker——容器与容器云》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具