对NodeJS模块机制的理解

时间:2020-12-10 17:43:20   收藏:0   阅读:27

1. Commonjs模块规范

1.1 模块引用

 
var math = require(‘math‘);

1.2 模块定义

上下文提供exports对象用于导出当前模块的方法和变量,并且他是唯一的导出出口,exports实际上是module.exports,而module.exports就是以一个暴露给外部的对象。

1.3 Commonjs 用法

// a.js
module.exports = {
    a: 1
}
// or 
exports.a = 1

// b.js
var module = require(‘./a.js‘)
module.a // -> log 1

1.4 原理

var module = require(‘./a.js‘)
module.a 
// 这里其实就是包装了一层立即执行函数,这样就不会污染全局变量了,
// 重要的是 module 这里,module 是 Node 独有的一个变量
module.exports = {
    a: 1
}
// module 基本实现
var module = {
  id: ‘xxxx‘, // 我总得知道怎么去找到他吧
  exports: {} // exports 就是个空对象
}
// 这个是为什么 exports 和 module.exports 用法相似的原因
var exports = module.exports 
var load = function (module) {
    // 导出的东西
    var a = 1
    module.exports = a
    return module.exports
};
// 然后当我 require 的时候去找到独特的
// id,然后将要使用的东西用立即执行函数包装下,over

 

2. Node的模块实现

在Node中引入模块,需要经历3个步骤

在node中,模块分为两类:一类是node提供的模块称为核心模块,一类是用户编写的成为文件模块。  

2.1 优先从缓存加载

Node对引入的模块都回进行缓存,而且缓存的是编译执行后的对象。  不管是核心模块还是文件模块,require()都一律采用缓存优先的方式。

2.2 路径分析和文件定位

2.2.1 模块标识符分析

2.2.2 文件定位

2.3 模块编译

每一个编译成功的模块都会将其文件路径索引缓存在Module._cache对象上,以提高二次引入性能  

2.3.1 js模块的编译

在编译的过程中,Node对获取的JS文件进行了头尾包装。这也是每个模块都能访问到 require、exports、module、__filename、__dirname的原因  

(funciton(exports, require, module, __filename, __dirname) {
  
  /* 自己写的代码  */

});

这样使得模块文件间都进行了作用域隔离,不用担心变量污染全局。

为moudle.exports赋值,exports对象是通过形参的方式传入,直接赋值形参会改变形参的引用,但并不能改变作用域外的值。

exports = function() {
  // my class
}

var change = function(a) {
  a = 100;
}

var a = 10;
change(a);
console.log(a); // => 10

如果要达到require引入一个类的效果,请赋值给 module.exports对象。这个迂回的方案不改变形参的引用。

2.3.2 C/C++ 模块的编译

Node调用process.dlopen()方法进行加载和执行。

实际上 .node模块并不需要编译,因为它是编写C/C++模块之后编译生成的,所以这里只有加载和执行的过程。在执行的过程中,模块exports对象与.node模块产生练习,然后返回给调用者。

 

3. 核心模块

Node的核心模块在编译成可执行文件的过程中被编译进了二进制文件。核心模块其实分为C/C++编写的和JavaScript编写的两部分,其中C/C++文件存放在Node项目的src目录下,JavaScript文件存放在lib目录下。  

  1. C/C++拓展模块

  2. 模块调用栈

  3. 前后端公用模块

  4. 模块侧重点

资源搜索网站大全 https://www.renrenfan.com.cn 广州VI设计公司https://www.houdianzi.com

4. AMD规范

Asynchronous Moudle Definition “异步模块定义”, AMD需要在声明的时候指定所有的依赖,通过形参传递依赖到模块内容中。  

定义如下

define(id?, dependencies, factory);

 

5. CMD 规范

与AMD主要区别在于定于模块与依赖引入部分。  

CMD支持动态引入

define(funtion(require, exports, moudle) {
  // The module code goes here
})

原文:https://www.cnblogs.com/xiaonian8/p/14113623.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!