一、模块分类

  1. 由Node提供的模块,称为核心模块;部分核心模块在Node源代码的编译过程中,编译进了二进制执行文件。在node进程启动时,该部分就直接加载进内存,文件定位和编译执行的步骤可以省略掉,并且在路径分析中优先判断,所以它的加载速度是最快的
  2. 用户编写的模块,成文文件模块;文件模块在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程,速度比核心模块慢。

二、模块规范(CommonJs)

  1. 模块的引用 
    1.  var http = require('math');
    2. 在CommonJs中存在require()方法,这个方法接受模块标识,以此引入一个模块的API到当前的上下文中。
  2. 模块定义
    1. 用exports对象导出当前模块的方法或者变量,并且它是唯一导出的出口。在模块中,还存在module对象,代表模块本身,而exports是module的属性。在node中,一个文件就是一个模块,将方法挂载在exports对象上作为属性即可定义导出的方式。

          

//math.js

exports.add = function(){
var sum = 0,
i =0 ,
args = arguments,
l =args.length;
while (i<1){
sum += args[i++];
}
return sum
} //program.js var math = require('math');//引入自定义模块(math.js) exports.increment = function(val){
return math.add(val,1);//使用模块定义的方法
};

3.模块标识

    模块标识就是传递给require()方法的参数,它必须是符合小驼峰命名的字符串,或者以. 、..开头的相对路径,或者绝对路径,可以没有后缀名.js

三、 Node模块实现

实现三步骤

1.路径分析

通过标识符进行模块查找,分几类

  1. 核心模块,如http,fs,path等。
  2. .或..开始的相对路径文件模块。
  3. 以/开始的绝对路径文件模块
  4. 非路径形式的文件模块,如自定义的connect模块。

加载方式和优先级

  • 核心模块的优先级仅此于缓存加载
  • 路径形式的文件模块,require()方法在分析的时候会转为真实路径,并以真实路径作为索引,将编译执行后的结果放到缓存中,以使二次加载时更快。
  • 自定义模块指的是非核心模块,也不是路径行驶的标识符,它是一种特殊的文件模块,可能是文件或包的形式。这类模块查找最费时。
2.文件定位

注意:从缓存加载的优化策略使得二次引入是不需要路径分析、文件定位、编译执行的过程,大大提高了再次加载模块时的效率。

在文件定位的过程中,还要注意一些细节,包括文件扩展名的分析、目录和包的处理。

  • 文件扩展名分析

    • Node会按.js,.json,.node的次序补足扩展名,依次尝试。尝试过程中需要调用fs模块同步阻塞式地判断文件是否存在。因为Node是单线程的,所以这里会引起性能问题。
    • 小诀窍:1.如果是.node,.json文件,在传递给require()的标识符中带上扩展名。2.同步配合缓存
  • 目录分析和包
    • ruquire()通过分析文件扩展名后可能没有查找到对应的文件,但却得到一个目录,Node将把目录当作一个包来处理
    • 在这个过程中,Node在当前目录下查找package.json(CommonJs包规范定义的包描述文件),通过JSON.parse()解析出包描述对象,从中取出main属性指定的文件名来定位,如果指定的文件错误,或没有package.json文件,Node将index当作默认文件名,然后依次查找index.js,index.json,index.node。若还是没有,则抛出查找异常错误。
3.编译执行

每个文件模块都是一个对象,定位到具体文件后,Node就会新建一个模块对象,然后根据路径载入并编译。对于不同的文件扩展名,载入方法不同

  • .js文件。通过fs模块同步读取文件后编译执行。
  • .node文件,用C/C++编写的扩展文件,通过dlopen()方法加载最后编译生成的文件。
  • .json文件,通过fs模块同步读取文件后,用JSON.parse()解析返回结果。
  • 其余扩展名文件。它们都当作.js文件载入。

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

Node学习笔记之模块实现的更多相关文章

  1. node 学习笔记 - Modules 模块加载系统 (1)

    本文同步自我的个人博客:http://www.52cik.com/2015/12/11/learn-node-modules-path.html 用了这么久的 require,但却没有系统的学习过 n ...

  2. node 学习笔记 - Modules 模块加载系统 (2)

    本文同步自我的个人博客:http://www.52cik.com/2015/12/14/learn-node-modules-module.html 上一篇讲了模块是如何被寻找到然后加载进来的,这篇则 ...

  3. node学习笔记6——自定义模块

    自定义模块三大关键词: require——引入模块: exports——单个输出: module——批量输出. 从例子下手: 1.创建module.js: exports.a=22; exports. ...

  4. node学习笔记(二)(ajax方式向node后台提交数据)

    通过ajax向node后台提交数据过程(附手写前后台代码),并总结post与get的区别 POST 前台代码 //CSS简单给点样式 <style> form{ width: 200px; ...

  5. Python学习笔记—itertools模块

    这篇是看wklken的<Python进阶-Itertools模块小结> 学习itertools模块的学习笔记 在看itertools中各函数的源代码时,刚开始还比较轻松,但后面看起来就比较 ...

  6. node学习笔记3——文件操作fs

    文件操作关键字: http('fs') ——  请求 node 里面的 http 模块 readFile ——  读文件,参数包括 文件名,回调函数 writeFile ——  写文件,参数包括 文件 ...

  7. Python学习笔记之模块与包

    一.模块 1.模块的概念 模块这一概念很大程度上是为了解决代码的可重用性而出现的,其实这一概念并没有多复杂,简单来说不过是一个后缀为 .py 的 Python 文件而已 例如,我在某个工作中经常需要打 ...

  8. node学习笔记

    一.准备(github地址) 什么是Javascript? ... Javascript能做什么? ..... 浏览器中的Javascript可以做什么? 操作DOM(增删改查) AJAX/跨域 BO ...

  9. node学习笔记(三)

    //事件驱动events //events是node最重要的模块没有之一,因为node.js本身的架构就是事件式的,而他提供了唯一的接口,所以堪称node.js事件编程的基石; //events几乎被 ...

随机推荐

  1. React之浅拷贝与深拷贝

    最近发现的一个bug让我从react框架角度重新复习了一遍浅拷贝与深拷贝. 浅拷贝,就是两个变量都是指向一个地址,改变了一个变量,那另一个变量也随之改变.这就是浅拷贝带来的副作用,两个变量会相互影响到 ...

  2. 移动端meta标签设置

    移动端meta标签设置 1.设置当前html文件的字符编码 <meta charset="UTF-8"> 1 2设置浏览器的兼容模式(让IE使用最新的浏览器渲染) &l ...

  3. redis 命令select、dbsize、清空数据库、info、client

    select 切换库 dbsize 当前库中数据条数 清空数据库 flushdb | flushall 清空数据,一个是清空当前库,一个清空当前实例 查看服务器及redis相关信息 infoinfo ...

  4. INFO: Font Metrics and the Use of Negative lfHeight

    INFO: Font Metrics and the Use of Negative lfHeight  Print  Email   Article translations  Article ID ...

  5. vue.js高仿饿了么(前期整理)

    1.熟悉项目开发流程 需求分析——>脚手架工具——>数据mock——>架构设计——>代码编写——>自测——>编译打包. 2.熟悉代码规范 从架构设计.组件抽象.模块 ...

  6. Eigen学习之简单线性方程与矩阵分解

    Eigen提供了解线性方程的计算方法,包括LU分解法,QR分解法,SVD(奇异值分解).特征值分解等.对于一般形式如下的线性系统: 解决上述方程的方式一般是将矩阵A进行分解,当然最基本的方法是高斯消元 ...

  7. 转: Dubbo远程调用服务框架原理与示例

    Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和  Spring 框架无缝集成. 主要核心部件: Remoting:  网络通 ...

  8. gitbook 入门

    安装 gitbook 插件 npm install gitbook-cli -g 或者 yarn global add gitbook-cli 初使化目录 gitbook init 会发现目录下面多了 ...

  9. 解决js跨域

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  10. C# 标准的MD5加密32位

    标准的MD5加密32位小写的: public static string GetMD5(string myString) { MD5 md5 = new MD5CryptoServiceProvide ...