Node.js学习教程之Module模块

所属分类: 网络编程 / JavaScript 阅读数: 1457
收藏 0 赞 0 分享

前言

采用了 Commonjs 规范,通过 module.exports、require 来导出和导入模块。模块加载机制中,采用了延迟加载的策略。就是说在用到的情况下,系统模块才会被加载,等加载完成后会放到 binding_cache 中。

分类(模块类型)

系统模块

  • 核心模块(native 模块),http、buffer、fs 等,底层调用的内建模块 (C/C++);
  • C/C++ 模块(built-in 内建模块),供 native 模块调用;

第三方模块

  • 第三方维护的模块,比如 express、koa、moment.js 等;
  • 本地维护的模块(以路径形式的文件模块)比如 .、..、/ 开头的;

文件形式

  • javaScript 模块,module.js;
  • json 模块,module.json;
  • C/C++ 模块,编译后扩展名为 .node,module.node;

加载机制

加载步骤

经历 路径分析、文件定位和编译执行。

加载顺序

  1. 系统缓存,一个模块被执行后会被缓存起来,提高再次加载速度;
  2. 系统模块,即原生模块,部分核心模块已经被编译成二进制,省略了 路径分析、文件定位,会直接被加载到了内存中,其中系统模块定义在源码的 lib 目录下;
  3. 文件模块,优先加载 .、..、/ 开头的,会依次按照 .js、.json、.node 进行扩展名补足尝试(文件没有加上扩展名),最好还是加上文件的扩展名。
  4. 目录模块,文件模块加载过程中,没有找到,但发现一个同样的目录名,就会将这个目录当作一个包来处理。这块采用了 Commonjs 规范,在文件 package.json 中查找;
  5. node_module 模块,如果系统模块、路径文件模块都找不到,Node.js 会从当前模块的父目录开始查找,直到系统的根目录;


关于缓存问题

模块缓存后,可以通过 require.cache 查看已缓存的模块。

// 模块文件 require.module.js
module.exports = {
  name: 'pr',
  say(){ }
}
// 引用模块文件 require.cache.js
require('./require.module');

console.log('require.cache ----- ');
console.log(require.cache);

对象引用

1.exports 与 module.exports 关系

const exports = module.exports;

所以就不能改变 exports 的指向,可以这样

exports.info = {
  name: 'pr',
  age: 30
}

module.exports = {
  name: 'pr',
  age: 30
}

模块循环引用

模块 moduleA.js 和 moduleB.js 两个模块互相引用,会怎样?

// moduleA.js
console.log('模块 moduleA');
exports.name = 'moduleA name';

age = 27;

const moduleB = require('./moduleB.js');
console.log('moduleA require moduleB =>', moduleB.name);
// moduleB.js
console.log('模块 moduleB');
exports.name = 'moduleB name';

const moduleA = require('./moduleA.js');
console.log('moduleB require moduleA =>', moduleA.name);

  • 启动模块 node moduleA.js,会打印 模块 moduleA;
  • 模块 moduleA.js 中加载 moduleB.js,打印 模块 moduleB;
  • 模块 moduleB.js 中又加载 moduleA.js,此时模块 moduleA.js 还没有执行完,返回模块 moduleA.js 的 exports 对象给到模块 moduleB.js;
  • 模块 moduleB.js 加载完后,其中有个 moduleA.js 中挂载了全局的变量 age,所以能打印出来,最后将模块 moduleB.js 的 exports 对象给到模块 moduleA.js;

很有意思的是,在代码执行前,会用一个封装器将执行代码段封装起来

(function(exports, require, module, __filename, __dirname) {
  // something
});

本次代码 Github

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

学习javascript文件加载优化

这篇文章主要为大家详细介绍了javascript文件加载优化,三种方式实现js文件加载优化,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

jQuery on()绑定动态元素出现的问题小结

jQuery on()方法是官方推荐的绑定事件的一个方法。使用 on() 方法可以给将来动态创建的动态元素绑定指定的事件,通过本文给大家介绍jQuery on()绑定动态元素出现的问题小结,需要的朋友参考下
收藏 0 赞 0 分享

基于JavaScript实现弹出框效果

弹出框在网站页面中是必不可少的一部分,今天借助脚本之家平台给大家分享使用js实现简单的弹出框效果,感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换

这篇文章主要介绍了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

JavaScript深度复制(deep clone)的实现方法

本文给大家介绍JavaScript深度复制(deep clone)的实现方法,涉及到js深度复制相关知识,本文介绍的非常详细,特此分享脚本之家平台供大家参考
收藏 0 赞 0 分享

jQuery实现简单的DIV拖动效果

这篇文章主要介绍了jQuery实现简单的DIV拖动效果,涉及jQuery针对鼠标事件的响应及页面元素的动态操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

javascript每日必学之循环

javascript每日必学之循环,本文的主要内容就是循环,死循环时进行bug调式,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

javascript下使用Promise封装FileReader

这篇文章主要介绍了javascript下使用Promise封装FileReader,需要的朋友可以参考下
收藏 0 赞 0 分享

js下将金额数字每三位一逗号分隔

这篇文章主要介绍了js下将金额数字每三位一逗号分隔的相关资料,还附加了一个小功能,小数位保留两位,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

使用jQuery的easydrag插件实现可拖动的DIV弹出框

EasyDrag 是一个用来实现页面元素拖拉的 jQuery 插件。接下来通过本文给大家介绍使用jQuery的easydrag插件实现可拖动的DIV弹出框,感兴趣的朋友一起学习吧
收藏 0 赞 0 分享
查看更多