Node.js 中的模块机制

简介: Node.js 中的模块机制

CommonJS

  • 模块引用
var math = require('math');
  • 模块定义

    • 上下文提供 exports 对象用于导出当前模块的方法或者变量,并且是唯一导出的出口
    • 模块中,还存在一个 module 对象,代表模块自身, exports 是 module 的属性
    • Node 中,一个文件就是一个模块
// math.js
exports.add = function () {
  var sum = 0,
    i = 0,
    args = arguments,
    l = arguments.length;
    while (i < l) {
      sum += args[i++];
    }
    return sum;
};
  • 模块标识

    • 传递给 require() 的参数,必须是符合小驼峰命名的字符串,或者 以 ... 开头的相对路径 或 绝对路径,结尾可以没有文件名后缀

模块实现

  • 实现

    1. 路径分析
    2. 文件定位
    3. 编译执行
  • 分类

    • 核心模块,Node 提供(核心模块在 Node 源代码编译过程中,编译进了二进制执行文件,在 Node 进程启动时,部分核心模块就直接被加载进内存中,加载速度快)
    • 文件模块,用户编写(在运行时动态加载,需要完成的路径分析、文件定位、难以执行过程,加载速度慢)
  • 优先缓存加载
  • 路径分析和文件定位

    • 模块标识符分析

      • 核心模块,最快
      • 路径形式的文件模块,较慢
      • 自定义模块(如文件或包),查找费时,最慢
    • 文件定位

      • 文件扩展名分析(不含扩展名时,按.js.node.json 次序补足,加上扩展名会加快速度)
      • 目录分析和包

        • 没有找到对应文件但发现一个目,会按照包处理
  • 模块编译

    • .js文件 通过 fs 模块同步读取文件后编译执行
    • .node文件 C/C++ 编写的扩展文件,通过 dlopen() 方法加载最后编译生成的文件
    • .json文件 通过 fs 模块同步读取后,用 JSON.parse() 解析返回结果
    • 其余扩展名文件,都按 .js 文件载入
// 一个正常的 JavaScript 文件会被包装成如下
(function (exports, require, module, __filename, __dirname) {
  var math = require('math');
  exports.area = function (radius) {
    return Math.PI * radius * radius;
  };
});

包与 npm

  • 包结构

    • package.json 包描述文件
    • bin 用于存放可执行二进制文件的目录
    • lib 用于存放 JS 代码的目录
    • doc 用于存放文档的目录
    • test 用于存放单元测试的代码
  • 包描述文件与 NPM

    • CommonJS 为 package.json 定义的必需字段

      • name
      • description
      • version major.minor.revision 参考 semver.org
      • keywords
      • maintainers
      • contributors
      • bugs
      • licenses
      • repositories
      • dependencies
      • homepage
      • os
      • cpu
      • engine
      • builtin
      • directories
      • implements
      • scripts
    • npm 新增字段

      • author
      • bin
      • main
      • devDependencies

前后端共用模块

  • AMD (CommonJS 模块规范的一个延伸)
// define(id?, dependencies?, factory);
define(function() {
  var exports = {};
  exports.sayHello = function() {
    alert('Hello from module ', module.id);
  };
  return exports;
});
  • CMD 规范
// define(factory);
define(function(require, exports, module) {
  // The module code goes here
});
  • 兼容多种模块规范
;(function (name, definition) {
  // 检测上下文环境是否为 AMD 或 CMD
  var hasDefine = typeof define === 'function',
    // 检查上下文环境是否为 Node
    hasExports = typeof module !== 'undefined' && module.exports;
  
  if (hasDefine) {
    // AMD 环境或 CMD 环境
    define(definition)
  } else if (hasExports) {
    // 定义为普通 Node 模块
    module.exports = definition();
  } else {
    // 将模块的执行结果挂在 window 中
    this[name] = definition();
  }
})('hello', function() {
  var hello = function() {};
  return hello;
});
相关文章
|
1月前
|
存储 JavaScript 前端开发
深入理解JavaScript中的事件循环(Event Loop):机制与实现
【10月更文挑战第12天】深入理解JavaScript中的事件循环(Event Loop):机制与实现
80 3
|
1月前
|
缓存 JavaScript 安全
nodejs里面的http模块介绍和使用
综上所述,Node.js的http模块是构建Web服务的基础,其灵活性和强大功能,结合Node.js异步非阻塞的特点,为现代Web应用开发提供了坚实的基础。
105 62
|
14天前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第36天】在探索Node.js的奥秘之旅中,中间件的概念如同魔法一般,它让复杂的请求处理变得优雅而高效。本文将带你领略这一机制的魅力,从概念到实践,一步步揭示如何利用中间件简化和增强你的应用。
|
26天前
|
消息中间件 JavaScript 中间件
深入浅出Node.js中间件机制
【10月更文挑战第24天】在Node.js的世界里,中间件如同厨房中的调料,为后端服务增添风味。本文将带你走进Node.js的中间件机制,从基础概念到实际应用,一探究竟。通过生动的比喻和直观的代码示例,我们将一起解锁中间件的奥秘,让你轻松成为后端料理高手。
27 1
|
1月前
|
缓存 JSON JavaScript
Node.js模块系统
10月更文挑战第4天
40 2
|
1月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
32 0
|
1月前
|
JavaScript 应用服务中间件 Apache
Node.js Web 模块
10月更文挑战第7天
31 0
|
1月前
|
JavaScript 网络协议
Node.js 工具模块
10月更文挑战第7天
21 0
|
1月前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第4天】在探索Node.js的海洋中,中间件机制犹如一座灯塔,为开发者指引方向。本文将带你一探究竟,从浅入深地理解这一核心概念。我们将通过生动的比喻和实际代码示例,揭示中间件如何在请求和响应之间搭建桥梁,实现功能的扩展与定制。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
47 0
|
1月前
|
移动开发 JavaScript 前端开发
【JavaScript】JS执行机制--同步与异步
【JavaScript】JS执行机制--同步与异步
21 0