Node.js学习教程之Module模块


Posted in Javascript onSeptember 03, 2019

前言

采用了 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 会从当前模块的父目录开始查找,直到系统的根目录;

Node.js学习教程之Module模块

关于缓存问题

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

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

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

Node.js学习教程之Module模块

对象引用

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.js学习教程之Module模块

  • 启动模块 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 相关文章推荐
判断脚本加载是否完成的方法
May 26 Javascript
javascript动态添加样式(行内式/嵌入式/外链式等规则)
Jun 24 Javascript
点击弹出层外区域关闭弹出层jquery特效示例
Aug 25 Javascript
Javascript前端UI框架Kit使用指南之Kitjs简介
Nov 28 Javascript
完美实现bootstrap分页查询
Dec 09 Javascript
jQuery事件用法详解
Oct 06 Javascript
Vue数据驱动模拟实现1
Jan 11 Javascript
JavaScript中常见的八个陷阱总结
Jun 28 Javascript
使用prop解决一个checkbox选中后再次选中失效的问题
Jul 05 Javascript
angular5 子组件监听父组件传入值的变化方法
Sep 30 Javascript
Vue数字输入框组件的使用方法
Oct 19 Javascript
JS script脚本中async和defer区别详解
Jun 24 Javascript
vue动态绘制四分之三圆环图效果
Sep 03 #Javascript
微信小程序拼接图片链接无底洞深入探究
Sep 03 #Javascript
layui radio单选限制下一个radio单选的实例
Sep 03 #Javascript
JavaScript Array对象基本方法详解
Sep 03 #Javascript
微信小程序通过一个json实现分享朋友圈图片
Sep 03 #Javascript
layui 实现自动选择radio单选框(checked)的方法
Sep 03 #Javascript
Node.js fs模块(文件模块)创建、删除目录(文件)读取写入文件流的方法
Sep 03 #Javascript
You might like
高分R级DC动画剧《哈莉·奎茵》第二季正式预告首发
2020/04/09 欧美动漫
php自定义session示例分享
2014/04/22 PHP
PHP读取PPT文件的方法
2015/12/10 PHP
PHP异常处理定义与使用方法分析
2017/07/25 PHP
关于javascript中this关键字(翻译+自我理解)
2010/10/20 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
2013/02/18 Javascript
详解jQuery插件开发中的extend方法
2013/11/19 Javascript
js数组依据下标删除元素
2015/04/14 Javascript
javascript作用域、作用域链(菜鸟必看)
2016/06/16 Javascript
深入剖析JavaScript面向对象编程
2016/07/12 Javascript
基于BootStrap的Metronic框架实现页面链接收藏夹功能按钮移动收藏记录(使用Sortable进行拖动排序)
2016/08/29 Javascript
AngularJS表单和输入验证实例
2016/11/02 Javascript
微信小程序中setInterval的使用方法
2017/09/29 Javascript
vue.js-div滚动条隐藏但有滚动效果的实现方法
2018/03/03 Javascript
Vue 通过自定义指令回顾v-内置指令(小结)
2018/09/03 Javascript
angularjs通过过滤器返回超链接的方法
2018/10/26 Javascript
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
JS闭包原理及其使用场景解析
2020/12/03 Javascript
关于element的表单组件整理笔记
2021/02/05 Javascript
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
pandas把dataframe转成Series,改变列中值的类型方法
2018/04/10 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
python 控制Asterisk AMI接口外呼电话的例子
2019/08/08 Python
中外合拍动画首获奥斯卡提名,“上海出品”《飞奔去月球》能否拿下最终大奖?
2021/03/16 国漫
使用HTML5的File实现base64和图片的互转
2013/08/01 HTML / CSS
sealed修饰符是干什么的
2012/10/23 面试题
人力资源专员自我评价怎么写
2013/09/19 职场文书
违反学校规定检讨书
2014/01/18 职场文书
中班幼儿评语大全
2014/04/30 职场文书
供用电专业求职信
2014/07/07 职场文书
奶茶店创业计划书
2014/08/14 职场文书
支教个人总结
2015/03/04 职场文书
2015年12.4全国法制宣传日活动总结
2015/03/24 职场文书
应收账款管理制度
2015/08/06 职场文书
mysql备份策略的实现(全量备份+增量备份)
2021/07/07 MySQL
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏