Node模块加载原理

Node

Node.js 是一个基于"Chrome V8 引擎" 的JavaScript “运行环境”,其基本使用不再赘述。

node模块

NodeJS采用CommonJS规范实现了模块系统

node模块导出数据的几种方式
1.通过exports.xxx = xxx导出
2.通过module.exports.xxx = xxx导出
3.通过global.xxx = xxx导出
在这里插入图片描述

但是:
无论通过哪种方式导出, 使用时都需要先导入(require)才能使用
通过global.xxx方式导出不符合CommonJS规范, 不推荐使用
在这里插入图片描述

实现原理

我们先对模块原理进行分析:
node模块
1.在CommonJS规范中一个文件就是一个模块
2.在CommonJS规范中通过exports暴露数据
3.在CommonJS规范中通过require()导入模块

既然一个文件就是一个模块,那么我们要想使用就必须先通过require()导入模块,所以可以推断出require()的作用其实就是读取文件,那么要想了解Node是如何实现模块的, 必须先了解如何执行读取到的代码。

执行文件
若是通过fs读取文件,得到的将是二进制文件或字符串,但都无法直接执行,但是我们知道如果是字符串, 在JS中是有办法让它执行的:eval 或者 new Function;

通过eval执行代码和new Function执行代码:
缺点: 存在依赖关系, 字符串可以访问外界数据,不安全
在这里插入图片描述
通过NodeJS的vm虚拟机执行代码:
runInThisContext: 无权访问外部变量, 但是可以访问global
在这里插入图片描述
runInThisContext提供了一个安全的环境给我们自行字符串中的代码,不能访问本地的变量, 但是可以访问全局的变量(也就是global上的变量)

runInNewContext: 无权访问外部变量, 也不能访问global
在这里插入图片描述
runInNewContext提供了一个安全的环境给我们执行字符串中的代码,不能访问本地的变量, 也不能访问全局的变量(也就是global上的变量)

加载分析

通过对实现原理的分析,现在我们可以对它的加载进行逐步分析与实现了。

我们通过webstorm等IDE或浏览器对其执行过程进行监控,得到如下加载流程:
1.内部实现了一个require方法

function require(path) {
   
  return self.require(path);
}

2.通过Module对象的静态__load方法加载模块文件

Module.prototype.require = function(path) {
   
  return Module._load(path, this, /* isMain */ false);
};

3.通过Module对象的静态_resolveFilename方法, 得到绝对路径并添加后缀名

var filename = Module._resolveFilename(request, parent, isMain);

4.根据路径判断是否有缓存, 如果没有就创建一个新的Module模块对象并缓存起来

var cachedModule = Module._cache[filename];
if (cachedModule)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值