node之CommonJs模块

1.在 Node.js 模块系统中,每个文件都被视为独立的模块。

在执行模块代码之前,Node.js 将使用如下所示的函数封装器对其进行封装:

(function(exports, require, module, __filename, __dirname) {
// 模块代码实际存在于此处
});

通过这样做,Node.js 实现了以下几点:

  • 它将文件内定义的顶层变量(用 varconst 或 let 定义)保持在模块而不是全局对象的范围内。
  • 它有助于提供一些实际特定于模块的全局变量,例如:
    • module 和 exports 对象,实现者可以用来从模块中导出值。
    • 便利变量 __filename 和 __dirname,包含模块的绝对文件名和目录路径。

2.模块在第一次加载后被缓存。

这意味着(类似其他缓存)每次调用 require(module) 都会返回完全相同的对象(如果解析为相同的文件)。

如果 require.cache 没有被修改,则多次调用 require('foo') 不会导致模块代码被多次执行。 这是重要的特征。 有了它,可以返回“部分完成”的对象,从而允许加载传递依赖项,即使它们会导致循环。

要让模块多次执行代码,则导出函数,然后调用该函数。

模块根据其解析的文件名进行缓存。 由于模块可能会根据调用模块的位置(从 node_modules 文件夹加载)解析为不同的文件名,因此如果 require('foo') 解析为不同的文件,则不能保证 require('foo') 将始终返回完全相同的对象。

此外,在不区分大小写的文件系统或操作系统上,不同的解析文件名可以指向同一个文件,但缓存仍会将它们视为不同的模块,并将多次重新加载文件。 例如,require('./foo') 和 require('./FOO') 返回两个不同的对象,而不管 ./foo 和 ./FOO 是否是同一个文件。

3.当文件直接从 Node.js 运行时,则 require.main 设置为其 module。 这意味着可以通过测试 require.main === module 来确定文件是被直接运行。

4.当有循环 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);

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

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

$ 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

需要仔细规划以允许循环模块依赖项在应用程序中正常工作。

前端优质资源聚合,由浅入深,由近及远:前端网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FarmerLZJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值